@objectstack/console 17.5.0 → 17.7.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/CHANGELOG.md +806 -0
- package/dist/.objectstack-injection.json +2 -2
- package/dist/.objectui-sha +1 -1
- package/dist/assets/{ActionResultDialog-CLdIyOW6.js → ActionResultDialog-ChYnuROr.js} +3 -3
- package/dist/assets/{AiPendingActionsPage-OKYz66yR.js → AiPendingActionsPage-Dh3-i4BB.js} +1 -1
- package/dist/assets/{ApiConsolePage-CcrKovu8.js → ApiConsolePage-CKYEqlMs.js} +1 -1
- package/dist/assets/AppDocsIndex-B5Tky2xg.js +1 -0
- package/dist/assets/{AppManagementPage-D_xz8cTZ.js → AppManagementPage-ZwyvnHpM.js} +1 -1
- package/dist/assets/ApprovalsInboxPage-DD4fe0Em.js +1 -0
- package/dist/assets/{AuditLogPage-CoghqsZb.js → AuditLogPage-Sed6iMqP.js} +1 -1
- package/dist/assets/BookPage-DYjUsQIc.js +1 -0
- package/dist/assets/{ComponentNavView-BxsixSU9.js → ComponentNavView-DrlxM4SY.js} +1 -1
- package/dist/assets/CreateViewDialog-Cp72x_O7.js +1 -0
- package/dist/assets/DashboardView-juicRxcP.js +1 -0
- package/dist/assets/DocPage-CxJaQ-pC.js +1 -0
- package/dist/assets/{DocsIndex-B2zw_HAp.js → DocsIndex-LALVtIVR.js} +1 -1
- package/dist/assets/{DocsLayout-DezZ8x7_.js → DocsLayout-BAwlJQQf.js} +1 -1
- package/dist/assets/DocsSlug-CkF1E-Zs.js +1 -0
- package/dist/assets/ExpressionProvider-Dr0e99r1.js +1 -0
- package/dist/assets/FlowRunsPage-R3W3t2s4.js +1 -0
- package/dist/assets/{IntegrationsPage-2leVkVDH.js → IntegrationsPage-DIuFLEbF.js} +2 -2
- package/dist/assets/InterfaceListPage-BfoCldGu.js +1 -0
- package/dist/assets/{MarketplaceInstalledPage-EPPHSitW.js → MarketplaceInstalledPage-DyjhcUNB.js} +1 -1
- package/dist/assets/MarketplacePackagePage-BbO27Pgs.js +4 -0
- package/dist/assets/{MarketplacePage-BnQKykgv.js → MarketplacePage-DO2_b64U.js} +1 -1
- package/dist/assets/{MetadataInspector-BWxLkr0O.js → MetadataInspector-BQyu9pOE.js} +1 -1
- package/dist/assets/ObjectDataPage-DIY-yefK.js +1 -0
- package/dist/assets/PageView-C-qWu3Jw.js +1 -0
- package/dist/assets/ProfilePage-Qp8DL8CF.js +1 -0
- package/dist/assets/{PublicFormsPage-DlE6tck_.js → PublicFormsPage-D3AT2EH9.js} +1 -1
- package/dist/assets/RecordDetailView-B3XBEgk2.js +3 -0
- package/dist/assets/RecordFormPage-CcoZfUJ3.js +1 -0
- package/dist/assets/ReportDefaultInspector-DVcWM6sh.js +1 -0
- package/dist/assets/ReportView-pJCFptzp.js +2 -0
- package/dist/assets/RuntimeDraftBar-DObTyFu2.js +1 -0
- package/dist/assets/SchemaForm-BWSWYMLE.js +3 -0
- package/dist/assets/SearchResultsPage-ChVIzFob.js +1 -0
- package/dist/assets/{SettingsHub-BGKIj-Zq.js → SettingsHub-CPP9FDe8.js} +1 -1
- package/dist/assets/SettingsView-CrHAROu9.js +1 -0
- package/dist/assets/{SkeletonDetail-C8fMI-Mu.js → SkeletonDetail-CP-35B8x.js} +1 -1
- package/dist/assets/{af-BfSmLD34.js → af-Bhbso4Pg.js} +1 -1
- package/dist/assets/ai-BAPiCsNk.js +3 -0
- package/dist/assets/app-shell-eager-leaves-D9tgfJOe.js +1 -0
- package/dist/assets/{ar-B9ttrM75.js → ar-DG8TAFtm.js} +1 -1
- package/dist/assets/{ar-DZ-C1rn-cyl.js → ar-DZ-BtSien-d.js} +1 -1
- package/dist/assets/{ar-EG-BaDxKP_o.js → ar-EG-DpXC0zoY.js} +1 -1
- package/dist/assets/{ar-MA-DbxNEcmd.js → ar-MA-D1qVJLyE.js} +1 -1
- package/dist/assets/{ar-SA-DeC5LXcX.js → ar-SA-BIYKNgv8.js} +1 -1
- package/dist/assets/{ar-TN-C9KpTFJz.js → ar-TN-mUR5Mq3s.js} +1 -1
- package/dist/assets/{az-cMerDwRO.js → az-B7IqwHGK.js} +1 -1
- package/dist/assets/{be-ZTSbszQh.js → be-CnZyPaSX.js} +1 -1
- package/dist/assets/{be-tarask-BXZEUrgX.js → be-tarask--uMMCC7l.js} +1 -1
- package/dist/assets/{bg-BDogpmn5.js → bg-CZwuirtY.js} +1 -1
- package/dist/assets/{bn-Cz04uxmh.js → bn-BbOX0r-z.js} +1 -1
- package/dist/assets/{bs-CpFnCl-j.js → bs-B5W75cYR.js} +1 -1
- package/dist/assets/{ca-CHC4M52Z.js → ca-Be69LdIM.js} +1 -1
- package/dist/assets/{ckb-Dxw-RNm8.js → ckb-B-nKM1Vn.js} +1 -1
- package/dist/assets/contracts-DieHW666.js +1 -0
- package/dist/assets/{createDerive-DvA_JGNq.js → createDerive-CynsXU-B.js} +1 -1
- package/dist/assets/{cs-DsFaJ5Z7.js → cs-qHngxH7l.js} +1 -1
- package/dist/assets/{cy-FH4JFDTs.js → cy-DscO2Pgf.js} +1 -1
- package/dist/assets/{da-D1pVjaAq.js → da-vibkaLMF.js} +1 -1
- package/dist/assets/data-adapter-BDsrq0TX.js +2 -0
- package/dist/assets/{de-AT-DUMQCisj.js → de-AT--JneEuBw.js} +1 -1
- package/dist/assets/{de-DKrxSvnP.js → de-BCT78XYW.js} +1 -1
- package/dist/assets/default-inspector-registry-Dktr6x_q.js +1 -0
- package/dist/assets/dist-yh3dYtHt.js +14 -0
- package/dist/assets/drillUrlFilters-N0RngQg6.js +1 -0
- package/dist/assets/{el-l3-bHySV.js → el-Cl0y9T2b.js} +1 -1
- package/dist/assets/en-AU-By42tTB7.js +1 -0
- package/dist/assets/{en-CA-DGH5NF0a.js → en-CA-BqEEoj-Y.js} +1 -1
- package/dist/assets/en-GB-Cx8B9nkB.js +1 -0
- package/dist/assets/en-IE-CX9nv6uO.js +1 -0
- package/dist/assets/en-IN-ByGSBHa4.js +1 -0
- package/dist/assets/en-NZ-BPMwa2ZN.js +1 -0
- package/dist/assets/en-ZA-lj_N4R6c.js +1 -0
- package/dist/assets/{eo-CL6CXHZx.js → eo-oOXROuhF.js} +1 -1
- package/dist/assets/{es-BIJ0rksI.js → es-EudscwjH.js} +1 -1
- package/dist/assets/{et-BGgMzjm1.js → et-CB-5LLh6.js} +1 -1
- package/dist/assets/{eu-CqvAoRrX.js → eu-B4-hcseX.js} +1 -1
- package/dist/assets/{fa-IR-DNz3oA1-.js → fa-IR-CogavcMJ.js} +1 -1
- package/dist/assets/{fi-DNSfKWuW.js → fi-CIBE0mYa.js} +1 -1
- package/dist/assets/{formatLong-CHb9WA3O.js → formatLong-qqgm7lV1.js} +1 -1
- package/dist/assets/{fr-CA-CotiswPx.js → fr-CA-BugXMutW.js} +1 -1
- package/dist/assets/{fr-DYRJCirJ.js → fr-CDReXYWW.js} +1 -1
- package/dist/assets/{fr-CH-CpiEYWpc.js → fr-CH-fiTiB6X1.js} +1 -1
- package/dist/assets/framework-CAuH4h0L.js +35 -0
- package/dist/assets/{fy-B69yM3FE.js → fy-t_GzIAg_.js} +1 -1
- package/dist/assets/{gd-BAy8AsX6.js → gd-CSncIxtN.js} +1 -1
- package/dist/assets/{getIcon-BEVyC4y3.js → getIcon-BDkBRQFw.js} +1 -1
- package/dist/assets/{gl-soLn_weL.js → gl-_138Mj2S.js} +1 -1
- package/dist/assets/{gu-B19Yo9yC.js → gu-COfH-YUT.js} +1 -1
- package/dist/assets/{he-DYTPo33p.js → he-BXL4lOKY.js} +1 -1
- package/dist/assets/{hi-D2dIK7Oy.js → hi-kXuYI0TJ.js} +1 -1
- package/dist/assets/{highlighted-body-OFNGDK62-CExufvVt.js → highlighted-body-OFNGDK62-CK7x7Gzm.js} +1 -1
- package/dist/assets/{hr-BV-VOPMu.js → hr-DAOsQWzI.js} +1 -1
- package/dist/assets/{ht-C7MM4qkS.js → ht-Ch8SKz8p.js} +1 -1
- package/dist/assets/{hu-Rha1m2Ym.js → hu-q6W_rWPT.js} +1 -1
- package/dist/assets/{hy-CiTNgbdV.js → hy-0M8OmwnM.js} +1 -1
- package/dist/assets/i18n-DTfZonAM.js +17 -0
- package/dist/assets/i18n-locale-ar-O6rs-Cir.js +4 -0
- package/dist/assets/i18n-locale-de-CMc1jk4a.js +4 -0
- package/dist/assets/i18n-locale-en-CbRQO81h.js +4 -0
- package/dist/assets/i18n-locale-es-t47nyoCX.js +4 -0
- package/dist/assets/i18n-locale-fr-E425EqJM.js +4 -0
- package/dist/assets/i18n-locale-ja-y_fk77fz.js +4 -0
- package/dist/assets/i18n-locale-ko-CdnY2uCg.js +4 -0
- package/dist/assets/i18n-locale-pt-BaUOXS6y.js +4 -0
- package/dist/assets/i18n-locale-ru-pFlhX9wg.js +4 -0
- package/dist/assets/i18n-locale-zh-Dkj4ROTN.js +4 -0
- package/dist/assets/i18n-runtime-CdWyaiOD.js +1 -0
- package/dist/assets/{id-Cijsfjt-.js → id-BM_H1_jv.js} +1 -1
- package/dist/assets/index-ocmkyCt6.js +19 -0
- package/dist/assets/index-v2Ijn9Gr.css +2 -0
- package/dist/assets/{infrastructure-BHSync5f.js → infrastructure-CSnL6ntj.js} +2 -2
- package/dist/assets/integration-7NqwVHuJ.js +1 -0
- package/dist/assets/{is-xS1WTyeC.js → is-B_7jXZfS.js} +1 -1
- package/dist/assets/isSameWeek-D90tBsli.js +1 -0
- package/dist/assets/{it-C2i_c9sd.js → it-CBM0J9cD.js} +1 -1
- package/dist/assets/{it-CH-l516ZNXj.js → it-CH-BQltCNsR.js} +1 -1
- package/dist/assets/{ja-D9_ewLny.js → ja-DBjnsx21.js} +1 -1
- package/dist/assets/{ja-Hira-D_6ExgHw.js → ja-Hira-BZfSmj1i.js} +1 -1
- package/dist/assets/{ka-BYHGyees.js → ka-HwpuKgUY.js} +1 -1
- package/dist/assets/{kk-CbTFtuqb.js → kk-DLKA9paj.js} +1 -1
- package/dist/assets/{km-Dr2gwhIn.js → km-BU5kermq.js} +1 -1
- package/dist/assets/{kn-CprH8JD7.js → kn-BNFqbCoi.js} +1 -1
- package/dist/assets/{ko-CsFS2u5i.js → ko-D8n4uMqQ.js} +1 -1
- package/dist/assets/{lb-CbFKN7Ob.js → lb-B1empQ7m.js} +1 -1
- package/dist/assets/{lt-Bq0xkLp0.js → lt-gMukpK3G.js} +1 -1
- package/dist/assets/{lv-Cj6vg6Qo.js → lv-D2O5AnsZ.js} +1 -1
- package/dist/assets/{match-CiPp9BME.js → match-BTF6WqJh.js} +1 -1
- package/dist/assets/{match-C_jFGO9e.js → match-Cyum2eeW.js} +1 -1
- package/dist/assets/{match-Co4ivumx.js → match-ScHH8kYk.js} +1 -1
- package/dist/assets/mermaid-GHXKKRXX-D4H6EVJQ.js +1 -0
- package/dist/assets/metadata-admin-CEhVmXFv.js +9 -0
- package/dist/assets/{mk-MXFM99YL.js → mk-D-Zl0xVN.js} +1 -1
- package/dist/assets/{mn-D5Q9B6Jt.js → mn-jJbTslgD.js} +1 -1
- package/dist/assets/{ms-CCzPRldx.js → ms-CUuJHLA4.js} +1 -1
- package/dist/assets/{mt-mjJpN6xW.js → mt-yIcbfxKY.js} +1 -1
- package/dist/assets/{nb-BIlNqdEb.js → nb-D9WNypoj.js} +1 -1
- package/dist/assets/{nl-BE-FwXjQsmV.js → nl-BE-B1vKiw2h.js} +1 -1
- package/dist/assets/{nl-D2uBtIxG.js → nl-DC7b5e90.js} +1 -1
- package/dist/assets/{nn-B0loJ7SV.js → nn-uP4yJ9s0.js} +1 -1
- package/dist/assets/{oc-U7-yH1sO.js → oc-DHTqadJI.js} +1 -1
- package/dist/assets/{pl-mTy0JYgi.js → pl-Bxnnizf5.js} +1 -1
- package/dist/assets/plugin-calendar-b7C35ANT.js +1 -0
- package/dist/assets/plugin-charts-b-yVtmdI.js +7 -0
- package/dist/assets/plugin-chatbot-D1KW_oIO.js +122 -0
- package/dist/assets/plugin-dashboard-DTkPoPEb.js +6 -0
- package/dist/assets/plugin-form-UIRm-FpQ.js +1 -0
- package/dist/assets/plugin-gantt-9dtc8zzX.js +63 -0
- package/dist/assets/plugin-grid-Cp4RKtMJ.js +10 -0
- package/dist/assets/plugin-kanban-B2JOPZIJ.js +1 -0
- package/dist/assets/plugin-map-CBJcVJYk.js +1 -0
- package/dist/assets/{plugin-markdown-D1nTQc1T.js → plugin-markdown-CNlDzqP-.js} +1 -1
- package/dist/assets/plugin-report-IZzgQb-Q.js +59 -0
- package/dist/assets/plugin-timeline-DsmtjcJ3.js +1 -0
- package/dist/assets/plugin-tree-DTRPBdhe.js +1 -0
- package/dist/assets/plugin-view-D9ixsNDG.js +1 -0
- package/dist/assets/plugins-views-CnvkdSJK.js +3 -0
- package/dist/assets/{pt-BR-2KtO5Js1.js → pt-BR-D416seHT.js} +1 -1
- package/dist/assets/{pt-Bet5OOQf.js → pt-DwHBy9_c.js} +1 -1
- package/dist/assets/{ro-37U6sgzi.js → ro-DDf1X3Np.js} +1 -1
- package/dist/assets/{ru-CyuAY-5E.js → ru-8eM3mcgK.js} +1 -1
- package/dist/assets/{runtime-metadata-persistence-afAW-MeD.js → runtime-metadata-persistence-DX29lQ62.js} +1 -1
- package/dist/assets/{se-DeJabuC6.js → se-D4JvQeRX.js} +1 -1
- package/dist/assets/{sk-DWEpjfkR.js → sk-DvpgttGI.js} +1 -1
- package/dist/assets/{sl-4oSvNhIR.js → sl-B3gCZ-_a.js} +1 -1
- package/dist/assets/{sq-BjkBCaXW.js → sq-CVaTmL0V.js} +1 -1
- package/dist/assets/{sr-Dxm1DsRS.js → sr-CnH5Ffyz.js} +1 -1
- package/dist/assets/{sr-Latn-Dawg6oP2.js → sr-Latn-Dw9w61q6.js} +1 -1
- package/dist/assets/src-BUry7633.js +2 -0
- package/dist/assets/{src-C8NYjdVm.js → src-DMDT5a27.js} +1 -1
- package/dist/assets/src-ZxH3AOCu.js +16 -0
- package/dist/assets/{studioEntry-nXQP3iL0.js → studioEntry-DAqcBFtr.js} +1 -1
- package/dist/assets/{submitRedirect-jK-cEIbP.js → submitRedirect-iy0oOi7I.js} +1 -1
- package/dist/assets/{sv-CROOGJGz.js → sv-CU7wdxyK.js} +1 -1
- package/dist/assets/{ta-BZnTmFI_.js → ta-DPH6q0HR.js} +1 -1
- package/dist/assets/{te-BN0v0x5t.js → te-BSaThkGV.js} +1 -1
- package/dist/assets/{th-CBjKhp_U.js → th-NXP8_Qb8.js} +1 -1
- package/dist/assets/{tr-x0Ne4N4H.js → tr-DDXoH663.js} +1 -1
- package/dist/assets/types-zod-ChJ30y25.js +1 -0
- package/dist/assets/{ug-sgzNhsKo.js → ug-Guus6pPe.js} +1 -1
- package/dist/assets/ui-components-D8wcRNrt.js +37 -0
- package/dist/assets/ui-layout-BYO3rRIl.js +1 -0
- package/dist/assets/{uk-o_DQ5VHJ.js → uk-uiy4vsp8.js} +1 -1
- package/dist/assets/use-book-data-DFTswcKm.js +1 -0
- package/dist/assets/{useActionModal-CSvbHkQ7.js → useActionModal-h52Z5Pkl.js} +1 -1
- package/dist/assets/useCanAuthorMetadata-TDrVrYGB.js +1 -0
- package/dist/assets/useDatasetCatalog-BOd0Ybr1.js +1 -0
- package/dist/assets/useNavSelDeepLink-67Y4qCNO.js +1 -0
- package/dist/assets/useNavTargetLabel-D8lRdb6O.js +1 -0
- package/dist/assets/useOpenRecordList-C7oqUD3F.js +1 -0
- package/dist/assets/{usePackageL10n-CMx66am-.js → usePackageL10n-Jl2XiF2F.js} +1 -1
- package/dist/assets/{useSettingsLabel-Kkr2q0Oo.js → useSettingsLabel-CSpBDTdy.js} +1 -1
- package/dist/assets/{uz-Cyrl-DbtkQtz_.js → uz-Cyrl-Cmb5bvbf.js} +1 -1
- package/dist/assets/{uz-Be41d4jl.js → uz-DJWxoTz4.js} +1 -1
- package/dist/assets/vendor-objectstack-C4eD5dbT.js +139 -0
- package/dist/assets/{vi-84mZmklk.js → vi-Bb3QoIJC.js} +1 -1
- package/dist/assets/{zh-CN-DD1reegJ.js → zh-CN-C-Hts1ZR.js} +1 -1
- package/dist/assets/{zh-HK-B05u30WI.js → zh-HK-CtBAZ_ZS.js} +1 -1
- package/dist/assets/{zh-TW-Bb-WimPD.js → zh-TW-B7DDahD-.js} +1 -1
- package/dist/chunk-membership.json +116 -104
- package/dist/eager-closure.json +126 -120
- package/dist/index.html +4 -4
- package/dist/sdui.manifest.json +998 -115
- package/package.json +1 -1
- package/dist/assets/AppDocsIndex-F4zDq2zz.js +0 -1
- package/dist/assets/ApprovalsInboxPage-DrEUmaDb.js +0 -1
- package/dist/assets/CreateViewDialog-xyKlpLEW.js +0 -1
- package/dist/assets/DashboardView-CGC-_Om8.js +0 -1
- package/dist/assets/DocPage-CIZE5kdj.js +0 -1
- package/dist/assets/DocsSlug-DXdFdwlS.js +0 -1
- package/dist/assets/ExpressionProvider-DZfMwyMs.js +0 -1
- package/dist/assets/FlowRunsPage-CvY3nJMF.js +0 -1
- package/dist/assets/InterfaceListPage-BdECC_i3.js +0 -1
- package/dist/assets/MarketplacePackagePage-C7NOu2Ir.js +0 -4
- package/dist/assets/ObjectDataPage-BIzp65Mo.js +0 -1
- package/dist/assets/PageView-CVLgCRSF.js +0 -1
- package/dist/assets/ProfilePage-D2qGgxPK.js +0 -1
- package/dist/assets/RecordDetailView-DQKydU7X.js +0 -3
- package/dist/assets/RecordFormPage-BTjwxJIA.js +0 -1
- package/dist/assets/ReportDefaultInspector-DdsQAkd7.js +0 -1
- package/dist/assets/ReportView-GIdKJdOt.js +0 -2
- package/dist/assets/RuntimeDraftBar-BbMdi3Kp.js +0 -1
- package/dist/assets/SchemaForm-C8X1ve4p.js +0 -3
- package/dist/assets/SearchResultsPage-Jwhqsdyo.js +0 -1
- package/dist/assets/SettingsView-D8SMKdrc.js +0 -1
- package/dist/assets/app-shell-eager-leaves-CDVclng4.js +0 -1
- package/dist/assets/appRoute-DbnWDEa1.js +0 -1
- package/dist/assets/data-adapter-DMbe6Njk.js +0 -1
- package/dist/assets/default-inspector-registry-CpL3fFhl.js +0 -1
- package/dist/assets/dist-BXrEV1ag.js +0 -13
- package/dist/assets/drillUrlFilters-hi-2d3DW.js +0 -1
- package/dist/assets/en-AU-C6x7mDhH.js +0 -1
- package/dist/assets/en-GB-0-nho2eK.js +0 -1
- package/dist/assets/en-IE-2fC3BkfV.js +0 -1
- package/dist/assets/en-IN-C1QcFhxn.js +0 -1
- package/dist/assets/en-NZ-C80ptZT7.js +0 -1
- package/dist/assets/en-ZA-ByZDrjeb.js +0 -1
- package/dist/assets/framework-DcWkeiND.js +0 -35
- package/dist/assets/i18n-CEKxYdmD.js +0 -9
- package/dist/assets/i18n-locale-ar-DN7sl3GF.js +0 -4
- package/dist/assets/i18n-locale-de-C40JErvb.js +0 -4
- package/dist/assets/i18n-locale-en-CITPDIHy.js +0 -4
- package/dist/assets/i18n-locale-es-C8DdWN6c.js +0 -4
- package/dist/assets/i18n-locale-fr-COIdEZZl.js +0 -4
- package/dist/assets/i18n-locale-ja-DYF_rU_s.js +0 -4
- package/dist/assets/i18n-locale-ko-B-ODYAtX.js +0 -4
- package/dist/assets/i18n-locale-pt-CK1SyBIm.js +0 -4
- package/dist/assets/i18n-locale-ru-jLzvShMO.js +0 -4
- package/dist/assets/i18n-locale-zh-Bf9Gbbvl.js +0 -4
- package/dist/assets/i18n-runtime-CTgAQF4N.js +0 -1
- package/dist/assets/index-CLyvpiGc.css +0 -2
- package/dist/assets/index-CfnfGw5W.js +0 -20
- package/dist/assets/isSameWeek-DWYeNyh8.js +0 -1
- package/dist/assets/mermaid-GHXKKRXX-DVLc_uym.js +0 -1
- package/dist/assets/metadata-admin-CybaOCdO.js +0 -9
- package/dist/assets/nav-selection-Dzm_mA3C.js +0 -1
- package/dist/assets/plugin-calendar-CKRBcML7.js +0 -1
- package/dist/assets/plugin-charts-DGTJxXCB.js +0 -7
- package/dist/assets/plugin-chatbot-DwtwNA-y.js +0 -122
- package/dist/assets/plugin-dashboard-C1AYKmGX.js +0 -6
- package/dist/assets/plugin-form-CV8ZY04-.js +0 -1
- package/dist/assets/plugin-gantt-BRIb2_8G.js +0 -63
- package/dist/assets/plugin-grid-C9h7mRVv.js +0 -11
- package/dist/assets/plugin-kanban-BcJ0Dhys.js +0 -1
- package/dist/assets/plugin-map-D24ZUOUj.js +0 -1
- package/dist/assets/plugin-report-BfGintAq.js +0 -59
- package/dist/assets/plugin-timeline-CbBRq_qt.js +0 -1
- package/dist/assets/plugin-tree-BNX2A5J5.js +0 -1
- package/dist/assets/plugin-view-DzWQWYyH.js +0 -1
- package/dist/assets/plugins-views-DraK4xz0.js +0 -3
- package/dist/assets/src-B8lv0plz.js +0 -18
- package/dist/assets/src-DoDvT77T.js +0 -1
- package/dist/assets/types-zod-Y2RwUUeJ.js +0 -1
- package/dist/assets/ui-components-BTB1NkUW.js +0 -37
- package/dist/assets/ui-layout-bZfafwJa.js +0 -1
- package/dist/assets/use-book-data-C3eyZJSG.js +0 -1
- package/dist/assets/useOpenRecordList-B5-qaFUx.js +0 -1
- package/dist/assets/vendor-objectstack-XuWC71M9.js +0 -266
- package/dist/assets/vendor-zod-CHLW1iCr.js +0 -64
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./rolldown-runtime-C0FnF6B9.js";import{$ as t,$n as n,A as r,An as i,Ar as a,Cn as o,D as s,Dr as c,Fn as l,G as u,Gr as d,Gt as f,H as p,Hr as m,Ht as h,I as g,Ir as _,Jt as v,K as y,Kr as b,Kt as ee,L as x,Lt as te,Mn as ne,O as re,Or as ie,Ot as ae,Pn as oe,Pt as se,Q as ce,Qn as le,R as ue,Rt as de,S as fe,Sn as pe,T as me,Tt as he,U as ge,Ur as _e,Vr as ve,W as ye,Wr as be,Xt as xe,Yt as Se,_ as Ce,_n as we,_t as Te,b as Ee,bn as De,ct as Oe,d as ke,dt as Ae,et as je,ft as Me,gt as Ne,h as Pe,hn as Fe,ht as Ie,i as Le,ir as Re,j as ze,k as Be,kr as Ve,l as He,lt as Ue,m as We,mn as Ge,mt as Ke,nn as qe,nr as Je,nt as Ye,pn as Xe,pt as Ze,q as Qe,qn as $e,qt as et,r as tt,rn as nt,rr as rt,sn as S,st as it,tr as at,u as ot,un as st,v as ct,vn as lt,vr as ut,vt as dt,w as ft,wt as pt,x as mt,xn as ht,yt as gt,z as _t,zt as vt}from"./vendor-objectstack-XuWC71M9.js";var yt=e(((e,t)=>{t.exports={}}));nt();var C=yt(),bt=new Set([...ae,...Object.values(u)]);function xt(e){return ht(e).names}function St(e){return new Set(o(e))}function Ct(e){if(!e||typeof e!=`object`)return[];let t=e.objects;return Array.isArray(t)?t.filter(e=>!!e&&typeof e==`object`):t&&typeof t==`object`?Object.entries(t).filter(([,e])=>!!e&&typeof e==`object`).map(([e,t])=>({name:e,...t})):[]}function wt(e){let t=new Map;for(let n of Ct(e)){let e=typeof n.name==`string`&&n.name.length>0?n.name:void 0;if(!e)continue;let r=St(n);r.size>0&&t.set(e,r)}return t}function Tt(e,t){return`'${t}' is an injected system column with NO storage behind it: '${e}' is an external object (ADR-0015), so the remote database owns its schema and the platform registers this anchor without provisioning a column`}function Et(e,t){return`If the remote table really carries '${t}', declare it in ${e}'s own fields (mapped through the external binding's columnMap) so the reference resolves to a column you vouch for; otherwise drop the reference, or opt the object out of the injection (\`ownership: 'none'\` for the ownership anchors, \`systemFields: { audit: false }\` for the audit family).`}var Dt=new Set([`lookup`,`master_detail`,`user`,`tree`]);function Ot(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function w(e){return Array.isArray(e)?e.filter(Ot):Ot(e)?Object.entries(e).map(([e,t])=>({name:e,...Ot(t)?t:{}})):[]}function kt(e){return typeof e==`string`&&e.length>0?e:void 0}function At(e){let t=e.fields;if(!t||typeof t!=`object`)return null;let n=new Set,r=new Map;for(let e of w(t)){let t=kt(e.name);t&&(n.add(t),r.set(t,{type:typeof e.type==`string`?e.type:void 0,reference:kt(e.reference),multiple:e.multiple===!0||void 0}))}return n.size===0?null:{names:n,fields:r,injected:xt(e)}}function jt(e){let t=new Map;if(!e||typeof e!=`object`)return t;for(let n of w(e.objects)){let e=kt(n.name);e&&t.set(e,At(n))}return t}function Mt(e,t,n){let r=kt(t),i=kt(n);if(!r||!i)return;let a=i.split(`.`),o=r;for(let t=0;t<a.length-1;t++){if(!e.has(o))return{kind:`unknowable`,reason:`object-not-in-stack`,object:o};let n=e.get(o);if(!n)return{kind:`unknowable`,reason:`no-field-map`,object:o};let r=a[t],i=n.fields.get(r);if(!i)return n.injected.has(r)?{kind:`unknowable`,reason:`injected-hop`,object:o}:{kind:`hop-unknown`,at:t,segment:r,object:o,candidates:n.names};if(!i.type||!Dt.has(i.type))return{kind:`hop-not-relationship`,at:t,segment:r,object:o,type:i.type};if(!i.reference)return{kind:`hop-untargeted`,at:t,segment:r,object:o};o=i.reference}if(!e.has(o))return{kind:`unknowable`,reason:`object-not-in-stack`,object:o};let s=e.get(o);if(!s)return{kind:`unknowable`,reason:`no-field-map`,object:o};let c=a[a.length-1];return s.names.has(c)?{kind:`ok`,object:o,field:c,meta:s.fields.get(c)}:s.injected.has(c)?{kind:`ok`,object:o,field:c,injected:!0}:{kind:`field-unknown`,object:o,field:c,candidates:s.names}}function Nt(e){let t=new Set;if(!Array.isArray(e))return t;for(let n of e){if(typeof n!=`string`||!n)continue;let e=n.split(`.`);for(let n=1;n<=e.length;n++)t.add(e.slice(0,n).join(`.`))}return t}function Pt(e,t,n){switch(e.kind){case`ok`:case`unknowable`:case`hop-untargeted`:return;case`hop-unknown`:return{message:`${n} "${t}" traverses "${e.segment}", which is not a field on object "${e.object}".${T(e.segment,e.candidates)}`,detail:`Fields on "${e.object}": ${Rt(e.candidates)}.`};case`hop-not-relationship`:return{message:`${n} "${t}" traverses "${e.segment}", which is a${e.type?` \`${e.type}\``:`n ordinary`} field on object "${e.object}" and not a relationship \u2014 there is nothing to join through.`,detail:`Only ${[...Dt].sort().join(` / `)} fields are traversable (ADR-0021 derives every join from the object graph; you never write an ON clause).`};case`field-unknown`:return{message:`${n} "${t}" is not a field on object "${e.object}".${T(e.field,e.candidates)}`,detail:`Fields on "${e.object}": ${Rt(e.candidates)}.`}}}function Ft(e){return!e||e.kind===`unknowable`||e.kind===`hop-untargeted`}function It(e,t){let n,r=1/0;for(let i of t){let t;if(e.length>=3&&(i.includes(e)||e.includes(i)))t=Math.abs(i.length-e.length);else{let n=Lt(e,i);if(n>Math.max(2,Math.floor(e.length/3)))continue;t=100+n}t<r&&(r=t,n=i)}return n}function T(e,t){let n=It(e,t);return n?` Did you mean "${n}"?`:``}function Lt(e,t){let n=e.length,r=t.length;if(n===0)return r;if(r===0)return n;let i=Array.from({length:r+1},(e,t)=>t);for(let a=1;a<=n;a++){let n=[a,...Array(r).fill(0)];for(let o=1;o<=r;o++){let r=e[a-1]===t[o-1]?0:1;n[o]=Math.min(n[o-1]+1,i[o]+1,i[o-1]+r)}i=n}return i[r]}function Rt(e){let t=[...e].sort();return t.length>0?t.join(`, `):`(none)`}var zt=new Set([`filter`,`filters`,`runtimeFilter`,`relatedListFilter`]);function Bt(e,t){return typeof e==`string`&&e.length>0?e:t}function Vt(e,t,n,r,i=new Set){if(e&&typeof e==`object`&&!i.has(e)){if(i.add(e),Array.isArray(e)){e.forEach((e,a)=>Vt(e,`${t}[${a}]`,n,r,i));return}for(let[a,o]of Object.entries(e)){let e=`${t}.${a}`;if(zt.has(a)){r({value:o,path:e,where:n});continue}Vt(o,e,n,r,i)}}}function Ht(e,t,n){if(e&&typeof e==`object`)for(let{key:r,kind:i}of t)w(e[r]).forEach((e,t)=>{let a=Bt(e.name??e.id,`#${t}`);if(i===`dashboard`){(Array.isArray(e.widgets)?e.widgets:[]).forEach((e,i)=>{let o=Bt(e.id??e.title,`#${i}`);Vt(e,`${r}[${t}].widgets[${i}]`,`dashboard "${a}" \xB7 widget "${o}"`,n,new Set)});let{widgets:i,...o}=e;Vt(o,`${r}[${t}]`,`dashboard "${a}"`,n,new Set);return}Vt(e,`${r}[${t}]`,`${i} "${a}"`,n,new Set)})}var Ut=32;function Wt(e){return!!e&&typeof e==`object`&&!Array.isArray(e)&&!(e instanceof Date)}function Gt(e,t,n,r,i){if(!(i>Ut))for(let[a,o]of Object.entries(e)){let e=`${t}.${a}`;if(a===`$and`||a===`$or`){Array.isArray(o)&&o.forEach((t,a)=>{Wt(t)&&Gt(t,`${e}[${a}]`,n,r,i+1)});continue}if(a===`$not`){Wt(o)&&Gt(o,e,n,r,i+1);continue}if(a.startsWith(`$`))continue;let s=n?`${n}.${a}`:a;if(Wt(o)&&!Object.keys(o).some(e=>e.startsWith(`$`))&&Object.keys(o).length>0){Gt(o,e,s,r,i+1);continue}r({field:s,path:e})}}function Kt(e,t,n,r=0){if(!(r>Ut)){if(Array.isArray(e)){if(typeof e[0]==`string`&&typeof e[1]==`string`&&![`and`,`or`].includes(e[0].toLowerCase())&&h.has(e[1].toLowerCase())){n({field:e[0],path:`${t}[0]`});return}e.forEach((e,i)=>{typeof e!=`string`&&Kt(e,`${t}[${i}]`,n,r+1)});return}if(Wt(e)){if(typeof e.field==`string`&&typeof e.operator==`string`){n({field:e.field,path:`${t}.field`});return}Gt(e,t,``,n,r)}}}var qt=`widget-dataset-unknown`,Jt=`widget-dimension-unknown`,Yt=`widget-measure-unknown`,Xt=`chart-field-unknown`,Zt=`chart-config-missing`,Qt=`chart-measures-missing`,$t=`chart-dimensions-missing`,en=`widget-measures-missing`,tn=`table-count-only`,nn=`measure-aggregate-incoherent`,rn=`widget-legacy-analytics-shape`,an=`widget-legacy-analytics-unrenderable`,on=`dashboard-filter-field-unknown`,sn=`dashboard-filter-field-unprovisioned`,cn=`dashboard-filter-field-not-included`,ln=`widget-filter-field-unknown`,un=`widget-filter-field-not-included`,dn=`widget-sortby-unselected`,fn=[`categoryField`,`valueField`,`xAxisField`,`yAxisFields`,`aggregate`,`aggregation`,`rowField`,`columnField`];function pn(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`):[]}var mn=new Set([`combo`]),hn=new Set([`metric`,`kpi`,`gauge`,`solid-gauge`,`bullet`]),gn=new Set([`table`,`pivot`]),_n=new Set(oe.options.filter(e=>!hn.has(e)&&!gn.has(e)));function vn(e){return typeof e==`string`&&_n.has(e)}var yn=new Set(oe.options.filter(e=>!_n.has(e)));function bn(e){return typeof e==`string`&&yn.has(e)}function E(e){let t=[...e];return t.length>0?t.join(`, `):`(none)`}var xn=`dateRange`,Sn=`created_at`;function Cn(e){let t=new Map,n=e.dateRange;if(n&&typeof n==`object`){let e=n.field,r=typeof e==`string`&&e?e:Sn;t.set(xn,{name:xn,field:r})}for(let n of w(e.globalFilters)){if(typeof n.field!=`string`||!n.field)continue;let e=typeof n.name==`string`&&n.name?n.name:n.field,r=Array.isArray(n.targetWidgets)?n.targetWidgets.filter(e=>typeof e==`string`):void 0;t.set(e,{name:e,field:n.field,targetWidgets:r})}return[...t.values()]}function wn(e,t){let n=e.filterBindings,r=n&&typeof n==`object`?n[t.name]:void 0;if(r!==!1){if(typeof r==`string`&&r)return{field:r,explicit:!0};if(t.targetWidgets&&t.targetWidgets.length>0){let n=typeof e.id==`string`?e.id:void 0;if(!n||!t.targetWidgets.includes(n))return}return{field:t.field,explicit:!1}}}function Tn(e){let t=[],n=new Map;for(let t of w(e.datasets))typeof t.name==`string`&&n.set(t.name,t);let r=new Map;for(let t of w(e.objects)){if(typeof t.name!=`string`)continue;let e=new Map;for(let n of w(t.fields))typeof n.name==`string`&&typeof n.type==`string`&&e.set(n.name,n.type);r.set(t.name,e)}let i=wt(e),a=jt(e),o=w(e.datasets);for(let e=0;e<o.length;e++){let n=o[e],i=typeof n.object==`string`?r.get(n.object):void 0;if(!i)continue;let a=w(n.measures);for(let r=0;r<a.length;r++){let o=a[r],s=typeof o.field==`string`?o.field:void 0,c=typeof o.aggregate==`string`?o.aggregate:void 0;if(!s||!c)continue;let l=i.get(s);l&&st(c,l)&&t.push({severity:`warning`,rule:nn,where:`dataset "${typeof n.name==`string`?n.name:`(dataset ${e})`}" \u203A measure "${typeof o.name==`string`?o.name:`(measure ${r})`}"`,path:`datasets[${e}].measures[${r}]`,message:`measure "${o.name}" applies ${c} to ${l} field "${s}" \u2014 summed percentages are meaningless (they can exceed 100%).`,hint:`Use aggregate "avg" for percentage/rate fields (or "count" of records). If a running total is genuinely intended, suppress with: suppressWarnings: ['${nn}'] on the measure.`})}}let s=w(e.dashboards);for(let e=0;e<s.length;e++){let r=s[e],o=typeof r.name==`string`?r.name:`(dashboard ${e})`,c=Array.isArray(r.widgets)?r.widgets:[],l=Cn(r);for(let r=0;r<c.length;r++){let s=c[r],u=`dashboard "${o}" \u203A widget "${typeof s.id==`string`?s.id:`(widget ${r})`}"`,d=`dashboards[${e}].widgets[${r}]`,f=e=>Array.isArray(s.suppressWarnings)&&s.suppressWarnings.includes(e),p=e=>{e.severity===`warning`&&f(e.rule)||t.push({...e,where:u,path:e.path??d})},m=fn.filter(e=>s[e]!==void 0);if(m.length>0){let e=typeof s.options==`object`&&s.options!==null&&s.options.data!==void 0,t=s.dataset!==void 0||s.object!==void 0||s.data!==void 0||e,n=m.map(e=>`\`${e}\``).join(`, `),r=m.length>1,i="Bind a semantic dataset and select fields BY NAME: `dataset: '<name>', dimensions: [...], values: [...]`. Dataset-bound widgets render through DatasetWidget (pivot rows/cols come from `dimensions`, cell values from `values`).";p(t?{severity:`warning`,rule:rn,message:`sets legacy analytics key${r?`s`:``} ${n} that the ADR-0021 single-form cutover removed \u2014 the dashboard renderer ignores ${r?`them`:`it`}.`,hint:`${i} These inline keys are a no-op. Suppress with suppressWarnings: ['${rn}'] if intentional.`}:{severity:`error`,rule:an,message:`sets legacy analytics key${r?`s`:``} ${n} (removed by the ADR-0021 single-form cutover) and binds no data source (no \`dataset\`, \`object\`, or inline \`data\`) \u2014 it renders nothing.`,hint:`${i} The renderer ignores the legacy keys, so without a data source this widget has no data at all.`})}let h=typeof s.dataset==`string`?s.dataset:void 0,g=h?n.get(h):void 0;if(h&&!g&&p({severity:`error`,rule:qt,message:`dataset "${h}" does not resolve to a declared dataset.`,hint:`Declared datasets: ${E(n.keys())}.${T(h,n.keys())} Define the dataset with defineDataset() or fix the reference (ADR-0021).`}),!h){p({severity:`error`,rule:qt,message:"binds no `dataset` — the ADR-0021 widget shape requires one, so this widget resolves no data and renders empty.",hint:`Set \`dataset: '<name>'\` (plus \`values\`, and \`dimensions\` where the chart family needs them). Declared datasets: ${E(n.keys())}.`});continue}if(!g)continue;if(l.length>0){let e=typeof g.object==`string`?g.object:void 0,t=e?a.get(e):void 0;if(e&&t){let n=Nt(g.include);for(let r of l){let o=wn(s,r);if(!o)continue;let c=o.field,l=Mt(a,e,c);if(Ft(l)||!l)continue;let u=o.explicit?`binds dashboard filter \`${r.name}\` to field \`${c}\` (via filterBindings), but `:`inherits dashboard filter \`${r.name}(${c})\`, but `;if(l.kind!==`ok`){let n=c.includes(`.`)?Pt(l,c,`the effective field`):void 0;if(n){p({severity:`error`,rule:on,message:`${u}${n.message} The filter is ANDed into EVERY bound widget's analytics query, so the query addresses a column that does not exist.`,hint:`Point filterBindings: { ${r.name}: '<field>' } at a field that resolves on \`${e}\` \u2014 or at a \`relationship[.relationship].field\` path whose prefix is declared in dataset "${h}"'s \`include\` \u2014 or opt out with filterBindings: { ${r.name}: false }. ${n.detail}`});continue}p({severity:`error`,rule:on,message:o.explicit?`binds dashboard filter \`${r.name}\` to field \`${c}\` (via filterBindings), but object \`${e}\` (dataset "${h}") has no field \`${c}\`.`:`inherits dashboard filter \`${r.name}(${c})\`, but object \`${e}\` (dataset "${h}") has no field \`${c}\`.`,hint:o.explicit?`Point filterBindings: { ${r.name}: '<field>' } at a field that exists on \`${e}\`, or opt out with filterBindings: { ${r.name}: false }.${T(c,t.names)} Object fields: ${E(t.names)}.`:`Set filterBindings: { ${r.name}: false } on this widget to opt out, or re-target to an existing field with filterBindings: { ${r.name}: '<field>' }.${T(c,t.names)} Object fields: ${E(t.names)}.`});continue}let d=c.lastIndexOf(`.`);if(d>=0){let t=c.slice(0,d);if(!n.has(t)){p({severity:`error`,rule:cn,message:`${u}its relationship prefix "${t}" is not declared in dataset "${h}"'s \`include\` \u2014 and ADR-0021 joins ONLY declared paths, so no join is compiled and the column is out of this query's reach. The filter is ANDed into EVERY bound widget's analytics query, so the whole board renders empty, not one tile.`,hint:`Add "${t}" to dataset "${h}"'s include (declaring "a.b" implicitly includes "a"), filter on a field of "${e}" itself, or opt out with filterBindings: { ${r.name}: false }. Declared include paths: ${n.size>0?[...n].sort().join(`, `):`(none)`}.`});continue}}if(!l.injected)continue;let f=l.object,m=l.field;i.get(f)?.has(m)&&p({severity:`warning`,rule:sn,message:`${u}${Tt(f,m)}. The filter is ANDed into this widget's analytics query (#2501), so it can never match a real value \u2014 on SQLite it silently degrades to constant-false and the widget renders empty (HTTP 200, zero rows, no error).`,hint:`${Et(f,m)} A widget can also opt out with filterBindings: { ${r.name}: false }. Suppress with suppressWarnings: ['${sn}'] if the remote schema resolves it some other way.`})}}}if(s.filter!==void 0&&s.filter!==null){let e=typeof g.object==`string`?g.object:void 0,t=e?a.get(e):void 0;if(e&&t){let t=Nt(g.include);Kt(s.filter,`${d}.filter`,({field:n,path:r})=>{let i=Mt(a,e,n);if(Ft(i)||!i)return;let o=Pt(i,n,`filter key`);if(o){p({severity:`error`,rule:ln,path:r,message:`${o.message} The widget's own \`filter\` is ANDed into the dataset query as \`runtimeFilter\`, so the condition addresses a column that does not exist: the widget renders successfully and empty, and nothing reports the miss.`,hint:`Filter on a field that exists on "${e}" (dataset "${h}"), or on a \`relationship[.relationship].field\` path whose prefix is declared in that dataset's \`include\`. ${o.detail}`});return}let s=n.lastIndexOf(`.`);if(s<0)return;let c=n.slice(0,s);t.has(c)||p({severity:`error`,rule:un,path:r,message:`filter key "${n}" resolves on the object graph, but its relationship prefix "${c}" is not declared in dataset "${h}"'s \`include\` \u2014 and ADR-0021 joins ONLY declared paths, so no join is compiled and the column is out of this query's reach. The widget renders empty.`,hint:`Add "${c}" to dataset "${h}"'s include (declaring "a.b" implicitly includes "a"), or filter on a field of "${e}" itself. Declared include paths: ${t.size>0?[...t].sort().join(`, `):`(none)`}.`})})}}let _=new Set;for(let e of w(g.dimensions))typeof e.name==`string`&&_.add(e.name);let v=new Map;for(let e of w(g.measures))typeof e.name==`string`&&v.set(e.name,e);let y=pn(s.dimensions);for(let e=0;e<y.length;e++)_.has(y[e])||p({severity:`error`,rule:Jt,message:`dimensions[${e}] "${y[e]}" is not a dimension of dataset "${h}" (declared dimensions: ${E(_)}).`,hint:`Widgets select dataset dimensions BY NAME.${T(y[e],_)} Add the dimension to the dataset or fix the reference.`});let b=pn(s.values);for(let e=0;e<b.length;e++)v.has(b[e])||p({severity:`error`,rule:Yt,message:`values[${e}] "${b[e]}" is not a measure of dataset "${h}" (declared measures: ${E(v.keys())}).`,hint:`Widgets select dataset measures BY NAME, not by base column.${T(b[e],v.keys())} Add the measure to the dataset or fix the reference.`});let ee=s.options&&typeof s.options==`object`&&!Array.isArray(s.options)?s.options:void 0,x=typeof ee?.sortBy==`string`?ee.sortBy:void 0;if(x&&!y.includes(x)&&!b.includes(x)){let e=_.has(x)||v.has(x),t=[...y,...b];p({severity:`error`,rule:dn,path:`${d}.options.sortBy`,message:e?`options.sortBy "${x}" is declared by dataset "${h}" but is not selected by this widget (selects: ${E(t)}), so the query result will not contain that column and the authored order cannot be applied.`:`options.sortBy "${x}" is neither a \`dimensions\` nor a \`values\` entry of this widget (selects: ${E(t)}) \u2014 \`sortBy\` must name one this widget actually selects, so the authored order cannot be applied.`,hint:e?`Add "${x}" to this widget's ${_.has(x)?`dimensions`:`values`}, or order by something it already selects.${T(x,t)}`:`Point options.sortBy at one of this widget's selected names (${E(t)}).${T(x,t)} Ordering is applied to the query RESULT, so it can only name a column that result carries.`})}let te=s.chartConfig&&typeof s.chartConfig==`object`?s.chartConfig:void 0,ne=typeof s.type==`string`&&mn.has(s.type);if(te){let e=new Set(b.filter(e=>v.has(e))),t=`Suppress with suppressWarnings: ['${Xt}'] if the inert key is intentional.`,n=te.xAxis&&typeof te.xAxis==`object`?te.xAxis:void 0;n&&typeof n.field==`string`&&!_.has(n.field)&&!y.includes(n.field)&&p({severity:`warning`,rule:Xt,message:`chartConfig.xAxis.field "${n.field}" does not resolve to a dimension of dataset "${h}" (declared dimensions: ${E(_)}) \u2014 and the dashboard renderer ignores an authored axis \`field\` in any case: \`axisPresentation\` strips it, so the x-axis stays bound to this widget's first dimension (${E(y)}). The binding is a silent no-op, not a query that fails.`,hint:`Point xAxis.field at a dataset dimension name, or drop the key \u2014 \`xAxis\` carries presentation only (title, format, gridlines) and the axis binding comes from this widget's \`dimensions\`.${T(n.field,_)} ${t}`});let r=(n,r,i)=>{if(b.includes(r))return;let a=v.has(r),o=a?`chartConfig.${n} "${r}" is a measure of dataset "${h}" but is not selected in the widget's values (${E(b)})`:`chartConfig.${n} "${r}" does not resolve to a measure of dataset "${h}" (declared measures: ${E(v.keys())})`,s=i===`series`?`the dashboard renderer derives one series per selected measure and matches an authored entry BY NAME, so this entry pairs with no series and the presentation on it (mark, colour, stack, axis side) lands on nothing`:`the dashboard renderer ignores an authored axis \`field\` \u2014 \`axisPresentation\` strips it \u2014 so the y-axis bindings stay derived from this widget's values (${E(b)}) and the key re-points nothing`,c=a?`Add "${r}" to the widget's values, or bind the chart to a selected measure.`:`Post-cutover data is keyed by the dataset's measure NAME, not the base column.${T(r,e.size>0?e:v.keys())}`,l=i===`series`?"`series[].name` selects WHICH derived series the presentation lands on; it cannot add, remove or re-point one.":"`yAxis[]` carries presentation only (title, min/max, position); the bindings come from `values`.";p({severity:`warning`,rule:Xt,message:`${o} \u2014 ${s}. It is a silent no-op, not a query that fails.`,hint:`${c} ${l} ${t}`})},i=Array.isArray(te.yAxis)?te.yAxis:[];for(let e=0;e<i.length;e++){let t=i[e]?.field;typeof t==`string`&&r(`yAxis[${e}].field`,t,`axis`)}let a=Array.isArray(te.series)?te.series:[];for(let e=0;e<a.length;e++){let t=a[e]?.name;typeof t==`string`&&r(`series[${e}].name`,t,`series`)}}else ne&&p({severity:`warning`,rule:Zt,message:`'${s.type}' widget has no chartConfig \u2014 a combination chart takes its per-series mark from \`chartConfig.series[].type\`, and with none declared every measure (${E(b)}) draws with the same default mark, so the chart is not a combination at all. The data and the axis are unaffected: the renderer derives those from this widget's dimensions and values.`,hint:`Give each measure its mark \u2014 chartConfig: { series: [{ name: '<measure>', type: 'bar' | 'line' | 'area' }] } \u2014 naming measures this widget selects (${E(b)}). \`series[].name\` selects WHICH derived series the mark lands on; it cannot add, remove or re-point one. If one uniform mark is intentional, prefer that family's own widget type, or suppress with: suppressWarnings: ['${Zt}']`});if(b.length===0){if(vn(s.type))p({severity:`warning`,rule:Qt,message:`'${s.type}' widget selects no measures (\`values\` is empty), so the renderer short-circuits to the authoring placeholder "Pick measures (values) for this dataset widget." before any query runs \u2014 no chart is drawn at all.`,hint:`Select at least one measure of dataset "${h}" BY NAME \u2014 values: ['<measure>'] (declared measures: ${E(v.keys())}).`+(y.length===0?` This widget selects no \`dimensions\` either; a chart family needs one to plot against (see ${$t}).`:``)+` If the widget is deliberately still being authored, suppress with: suppressWarnings: ['${Qt}']`});else if(bn(s.type)){let e=hn.has(s.type)?`the single KPI number this tile is for is not drawn at all`:`no table is rendered at all`;p({severity:`warning`,rule:en,message:`'${s.type}' widget selects no measures (\`values\` is empty), so the renderer short-circuits to the authoring placeholder "Pick measures (values) for this dataset widget." before any query runs \u2014 ${e}.`,hint:`Select at least one measure of dataset "${h}" BY NAME \u2014 values: ['<measure>'] (declared measures: ${E(v.keys())}). A '${s.type}' widget needs no \`dimensions\`, so measures are the whole fix. If the widget is deliberately still being authored, suppress with: suppressWarnings: ['${en}']`})}}else y.length===0&&vn(s.type)&&p({severity:`warning`,rule:$t,message:`'${s.type}' widget selects no dimensions, so the renderer's \`isMetric\` test (\`METRIC_TYPES.has(widgetType) || dimensions.length === 0\`) is true and it draws a single KPI number instead of a '${s.type}' chart. The number is real, so nothing looks broken \u2014 the declared chart family is simply gone.`,hint:`Plot the chart against a dataset dimension \u2014 dimensions: ['<name>'] (declared dimensions: ${E(_)}) \u2014 or, if a single value IS what this tile should show, declare it as a 'metric' or 'kpi' widget so the type matches what renders. Suppress with: suppressWarnings: ['${$t}']`});if(s.type!==`table`&&s.type!==`pivot`||y.length>0||b.length===0)continue;let re=b.map(e=>v.get(e));re.some(e=>!e)||re.every(e=>e.aggregate===`count`&&!e.derived)&&p({severity:`warning`,rule:tn,message:`a '${s.type}' widget bound to dataset "${h}" selects only count measure(s) (${b.join(`, `)}) and no dimensions, so it renders a single summary row \u2014 not a per-record list.`,hint:`A flat record listing is not an analytics dataset. Model it as an object-bound ListView (ADR-0017) surfaced through app navigation, and use a 'metric' widget here if you only need the count. If a single-row table is intentional, add an explicit dimension or suppress with: suppressWarnings: ['${tn}']`})}}return t}var En=[`iteratorVariable`,`indexVariable`,`errorVariable`,`outputVariable`],Dn=`assignment`,On=[`variable`,`name`,`key`];function kn(e){let t=e.assignments,n=[];if(Array.isArray(t)){for(let e of t){if(!e||typeof e!=`object`)continue;let t=e;for(let e of On){let r=t[e];if(typeof r==`string`&&r){n.push(r);break}}}return n}return Object.keys(t&&typeof t==`object`?t:e)}function An(e,t){let n=new Set,r=e.variables;if(Array.isArray(r))for(let e of r){if(!e||typeof e!=`object`)continue;let t=e;typeof t.name==`string`&&t.name&&n.add(t.name)}for(let e of t)for(let t of w(e.nodes)){typeof t.id==`string`&&t.id&&n.add(t.id);let e=t.config;if(!e||typeof e!=`object`||Array.isArray(e))continue;let r=e;for(let e of En){let t=r[e];typeof t==`string`&&t&&n.add(t)}if(t.type===Dn)for(let e of kn(r))e&&n.add(e)}return n}var jn=64;function Mn(e){let t=[];for(let n=0;n<jn;n++){let n=Ae(e,t);if(n===null||t.includes(n))break;t.push(n)}return t}function Nn(e,t,n){if(t.size===0||n.length===0)return[];let r=new Set(n.filter(e=>t.has(e)));return r.size===0?[]:Mn(e).filter(e=>r.has(e))}function Pn(e,t){return`bare reference \`${e}\` is BOTH a declared flow variable and a field on \`${t}\` \u2014 a flow run seeds its declared variables FIRST and flattens the record's fields only where nothing is bound yet, so this reads the VARIABLE, the field is unreachable under its own name, and nothing reports the collision. Write \`record.${e}\` if you meant the field, or rename the variable if you meant the variable.`}var Fn=`Guard it with '!= null' — 'has(x)' does NOT do that: a declared field holding null is still PRESENT, so has(x) is true.`,In=new Set([`<`,`<=`,`>`,`>=`,`+`,`-`,`*`,`/`,`%`]),Ln=[`record`,`previous`];function Rn(e){return!!e&&typeof e==`object`&&typeof e.op==`string`}function zn(e){return Rn(e)&&e.op===`value`&&e.args===null}function Bn(e,t){if(!Rn(e)||e.op!==`.`&&e.op!==`.?`)return null;let n=e.args;if(!Array.isArray(n)||n.length<2)return null;let[r,i]=n;if(typeof i!=`string`||!Rn(r)||r.op!==`id`)return null;let a=r.args;return typeof a!=`string`||!t.includes(a)?null:{operand:`${a}.${i}`,field:i}}function Vn(e){let t=e.args;if(Rn(t))return[t];if(!Array.isArray(t))return[];let n=[];for(let e of t)if(Rn(e))n.push(e);else if(Array.isArray(e))for(let t of e)Rn(t)&&n.push(t);return n}function Hn(e){if(e.op!==`call`)return null;let t=e.args;return!Array.isArray(t)||typeof t[0]!=`string`?null:t[0]}function Un(e){let t=e.args;return!Array.isArray(t)||!Array.isArray(t[1])?[]:t[1]}function Wn(e,t){return new Set([...e,...t])}function Gn(e,t){let n=new Set;for(let r of e)t.has(r)&&n.add(r);return n}function Kn(e,t){if(!Rn(e))return new Set;switch(e.op){case`!=`:{let[n,r]=e.args??[];if(zn(r)){let e=Bn(n,t);return e?new Set([e.operand]):new Set}if(zn(n)){let e=Bn(r,t);return e?new Set([e.operand]):new Set}return new Set}case`&&`:{let[n,r]=e.args;return Wn(Kn(n,t),Kn(r,t))}case`||`:{let[n,r]=e.args;return Gn(Kn(n,t),Kn(r,t))}case`!_`:return qn(e.args,t);case`?:`:{let[,n,r]=e.args;return Gn(Kn(n,t),Kn(r,t))}default:return new Set}}function qn(e,t){if(!Rn(e))return new Set;switch(e.op){case`==`:{let[n,r]=e.args??[];if(zn(r)){let e=Bn(n,t);return e?new Set([e.operand]):new Set}if(zn(n)){let e=Bn(r,t);return e?new Set([e.operand]):new Set}return new Set}case`||`:{let[n,r]=e.args;return Wn(qn(n,t),qn(r,t))}case`&&`:{let[n,r]=e.args;return Gn(qn(n,t),qn(r,t))}case`!_`:return Kn(e.args,t);case`call`:{if(Hn(e)!==`isBlank`)return new Set;let[n]=Un(e),r=Bn(n,t);return r?new Set([r.operand]):new Set}default:return new Set}}function Jn(e,t,n){if(Rn(e)){if(Hn(e)===`has`)for(let r of Un(e)){let e=Bn(r,t);e&&n.add(e.operand)}for(let r of Vn(e))Jn(r,t,n)}}function Yn(e,t){if(typeof e!=`string`||!e.trim()||t.nullableFields.size===0)return[];let n=t.roots??Ln,r=Ne(e);if(!r)return[];let i=new Set;Jn(r,n,i);let a=[],o=new Set,s=(e,r,s)=>{let c=Bn(e,n);if(!c||!t.nullableFields.has(c.field)||s.has(c.operand))return;let l=`${c.operand}\0${r}`;o.has(l)||(o.add(l),a.push({operand:c.operand,field:c.field,operator:r,hasOnlyGuard:i.has(c.operand)}))},c=(e,t)=>{if(!Rn(e))return;let r=e.op;if(r===`&&`){let[r,i]=e.args;c(r,t),c(i,Wn(t,Kn(r,n)));return}if(r===`||`){let[r,i]=e.args;c(r,t),c(i,Wn(t,qn(r,n)));return}if(r===`?:`){let[r,i,a]=e.args;c(r,t),c(i,Wn(t,Kn(r,n))),c(a,Wn(t,qn(r,n)));return}if(r!==`call`||Hn(e)!==`has`){if(In.has(r)){let[n,i]=e.args;s(n,r,t),s(i,r,t),c(n,t),c(i,t);return}if(r===`-_`){s(e.args,`-`,t),c(e.args,t);return}for(let n of Vn(e))c(n,t)}};return c(r,new Set),a}var Xn={"fail-closed":`so the rule enforces nothing and the write is rejected fail-closed (#4649/#4763)`,"fail-open":"so the predicate is SKIPPED fail-open — the field is never actually required, the write proceeds unchecked, and the only trace is a `requiredWhen … failed to evaluate — skipped` log line (#4649/#4811)"};function Zn(e,t,n,r=`fail-closed`){let i=t?`'${t}'`:`this object`,a=n.hasOnlyGuard?` \`has(${n.operand})\` does not guard it.`:``;return`${e} applies \`${n.operator}\` to \`${n.operand}\`, which ${i} declares as nullable (no \`required: true\`, no \`defaultValue\`).${a} At runtime the operand is null, CEL has no \`${n.operator}\` overload for null, and the whole predicate aborts \u2014 ${Xn[r]}. The predicate compares a value that is null. ${Fn}`}function Qn(e){let t=new Map;for(let n of e){let e=typeof n.name==`string`?n.name:void 0;if(!e)continue;let r=n.fields,i=[];Array.isArray(r)?i=w(r).map(e=>e.name).filter(e=>typeof e==`string`):r&&typeof r==`object`&&(i=Object.keys(r)),t.set(e,[...new Set([...i,...xt(n)])])}return t}var $n=[`record`,`previous`];function er(e){return!!e&&typeof e==`object`&&typeof e.op==`string`}function tr(e){let t=new Map,n=Ne(e);if(!n)return t;let r=[n];for(;r.length>0;){let e=r.pop();if(!er(e))continue;if((e.op===`.`||e.op===`.?`)&&Array.isArray(e.args)&&e.args.length>=2){let[n,r]=e.args;typeof r==`string`&&er(n)&&n.op===`id`&&typeof n.args==`string`&&$n.includes(n.args)&&(t.has(r)||t.set(r,`${n.args}.${r}`))}let n=e.args;if(er(n))r.push(n);else if(Array.isArray(n)){for(let e of n)if(er(e))r.push(e);else if(Array.isArray(e))for(let t of e)er(t)&&r.push(t)}}return t}function nr(e){let t=new Map;for(let n of e){let e=typeof n.name==`string`?n.name:void 0;if(!e)continue;let r=n.fields,i={};if(Array.isArray(r))for(let e of r){let t=e?.name,n=e?.type;typeof t==`string`&&typeof n==`string`&&(i[t]=n)}else if(r&&typeof r==`object`)for(let[e,t]of Object.entries(r)){let n=t?.type;typeof n==`string`&&(i[e]=n)}t.set(e,i)}return t}function rr(e){let t=e.fields;return Array.isArray(t)?t.filter(e=>e&&typeof e==`object`&&typeof e.name==`string`).map(e=>[e.name,e]):t&&typeof t==`object`?Object.entries(t).filter(([,e])=>!!e&&typeof e==`object`).map(([e,t])=>[e,t]):[]}function ir(e){if(e.required===!0||e.defaultValue!==void 0&&e.defaultValue!==null||e.type===`autonumber`)return!1;let t=e.options;return!(Array.isArray(t)&&t.some(e=>!!e&&typeof e==`object`&&e.default===!0))}function ar(e){let t=new Map;for(let n of e){let e=typeof n.name==`string`?n.name:void 0;if(!e)continue;let r=new Set;for(let[e,t]of rr(n))ir(t)&&r.add(e);t.set(e,r)}return t}function or(e){let t=Oe(e);return t.ok&&t.roots.includes(`parent`)}function sr(e){let t=0;for(let[,n]of rr(e)){if(n.type!==`master_detail`)continue;let e=n.reference;typeof e==`string`&&e.trim()!==``&&(t+=1)}return t}function cr(e){if(typeof e==`string`)return e;if(e&&typeof e==`object`){let t=e;if(typeof t.dialect==`string`&&t.dialect!==`cel`)return;if(typeof t.source==`string`)return t.source}}function lr(e,t){let n=[],r=typeof e.name==`string`?e.name:`?`,i=t?`${t} \u2192 '${r}'`:`'${r}'`,a=e.condition;a!=null&&n.push({label:`validation rule ${i}`,raw:a}),e.when!=null&&n.push({label:`validation rule ${i} when-predicate`,raw:e.when});for(let t of[`then`,`otherwise`]){let r=e[t];r&&typeof r==`object`&&!Array.isArray(r)&&n.push(...lr(r,`${i} ${t}`))}return n}var ur=[`record`,`previous`,`parent`],dr=[`app`],fr=[...it,...dr],pr=[`current_user`,`user`,`ctx`,`os`],mr=`the predicate faults, and a faulting rule never produces the verdict you declared — each slot resolves the fault to its own fallback, and none of those fallbacks is yours`,hr={visibleWhen:"the predicate no longer merely faults — and BOTH of its outcomes are wrong, in opposite directions. Under a host that publishes a predicate scope the renderer RESOLVES it (plugin-form's `sectionFields` copies this object rule onto the runtime form field and `resolveFieldRuleState` evaluates it with the host scope bound, objectui#6010) — so the control is hidden in that one form while NO server-side gate evaluates a field-level `visibleWhen` at all: the record still carries the value and every other reader still returns it, a SILENT enforcement gap. Where no host publishes a scope (the console public `/f/:slug` route, and every non-form reader) the root is unbound, the predicate faults and the renderer falls back to VISIBLE (`resolveFieldRuleState` evaluates visibility with `fallback: true`), leaving the field the test was meant to hide showing for everyone (#6146). The gap is the WORSE of the two — a visible fail-open gets reported, and a silent one does not",readonlyWhen:"the predicate faults — and the two ends fault in OPPOSITE directions. The server treats the field as LOCKED (`isReadonlyWhenLocked` will not waive a declared lock it could not evaluate, #4889) and drops your value from the payload, while the form still renders the field editable (`fallback: false`). The server is the one that decides: the field looks writable, the save reports success, and the value silently never lands",requiredWhen:`the predicate faults and the requirement is never enforced anywhere — the server logs it and SKIPS the check (fail-open, #4977 deliberately did not take #4889's carve-out) and the form does not mark the field required either, so a record saves with the field empty`,conditionalRequired:mr};function gr(e,t){let n=Oe(t);if(!n.ok)return null;let r=fr.filter(e=>!ur.includes(e)&&n.roots.includes(e));if(r.length===0)return null;let i=pr.find(e=>r.includes(e))??r[0],a=pr.includes(i)?"To gate the CHOICES of a select by user, move the predicate to the option's own `visibleWhen` (`options: [{ …, visibleWhen: … }]`) — the rule validator evaluates that one against `current_user` and its ADR-0068 aliases on every write, so the gate holds server-side. To hide the FIELD by role, declare field-level security on a permission set (`fields: { '<object>.<field>': { readable: false } }`), which the server enforces. To gate on record state, rewrite the predicate against `record`. Note that a form VIEW's own field predicate HAS bound these roots since objectui#6010 — but only in the renderer, so moving a server-enforced object rule there swaps a loud error for a silent enforcement gap; it is not a fourth answer.":i===`data`?"`data` is the root of a METADATA form (a `*.form` module — the metadata row being edited); this is an OBJECT field, whose runtime form binds the row as `record` — one key name, two form kinds, two roots. Rewrite `data.<key>` as `record.<field>`.":dr.includes(i)?`\`${i}\` is NOT declared platform-wide \u2014 it is an AMBIENT root, mounted only by the renderer (objectui app-shell's \`ExpressionProvider\` binds it beside \`current_user\` / \`user\` / \`ctx\` / \`os\` / \`data\` / \`features\`, and the spec's page-component schema records that ambient set as renderer behaviour, explicitly NOT contract-guaranteed). So it resolves in a form VIEW's own field predicate and on no server path at all, while a field-level object rule is server-enforced. \u26D4 Do NOT write \`record.${i}\`: \`${i}\` is not a field on this object, so that spelling only trades this diagnostic for an \`unknown field\` error on \`${i}\`. Rewrite the predicate against \`record\` (plus \`previous\`, and \`parent\` on a master-detail line item), or leave the \`${i}\`-dependent decision on the view's own field predicate where \`${i}\` IS bound \u2014 renderer-only, enforcing nothing server-side.`:`\`${i}\` is declared platform-wide and bound at OTHER evaluation sites (flow, automation, screen and action predicates), never at the field level. Rewrite the predicate against \`record\` (plus \`previous\`, and \`parent\` on a master-detail line item), or move the decision to a surface that binds \`${i}\`.`;return{root:i,message:`\`${e}\` reads \`${i}\`, but a field-level conditional rule binds only \`record\` (plus \`previous\`, and \`parent\` on a master-detail line item) \u2014 \`${i}\` is unbound here, so ${hr[e]??mr}. `+a}}function _r(e,t){return t.some(t=>e.startsWith(`bare reference \`${t}\``))}function vr(e){let t=[],n=w(e.objects),r=Qn(n),i=nr(n),a=ar(n),o=new Map;for(let e of n){let t=typeof e.name==`string`?e.name:void 0;if(!t)continue;let n=St(e);n.size>0&&o.set(t,n)}let s=(e,n,r)=>{if(!r)return;let i=o.get(r);if(!i)return;let a=cr(n);if(a)for(let[n,o]of tr(a))i.has(n)&&t.push({where:e,message:`\`${o}\` reads '${n}', an injected system column with NO storage behind it: '${r}' is an external object (ADR-0015), so the remote database owns its schema and the platform registers this anchor without provisioning a column. The predicate can never match a real value \u2014 on SQLite it silently degrades to constant-false (HTTP 200, zero rows, no error). If the remote table really carries this column, declare '${n}' in the object's own fields (mapped through the external binding's columnMap) so the reference resolves to a column you vouch for; otherwise drop the reference, or opt the object out of the injection (\`ownership: 'none'\` for the ownership anchors, \`systemFields: { audit: false }\` for the audit family).`,source:a,severity:`warning`})},c=(e,n,r,i,o=`fail-closed`)=>{if(!i)return;let s=a.get(i);if(!s||s.size===0)return;let c=cr(r);if(c)for(let r of Yn(c,{nullableFields:s}))t.push({where:e,message:Zn(n,i,r,o),source:c,severity:`error`})},l=(e,n,a,o=`flattened`,c)=>{if(n==null)return;let l=a?r.get(a):void 0,u=a?i.get(a):void 0,d=gt(`predicate`,n,a?{objectName:a,fields:l,fieldTypes:u,scope:o}:{scope:o});for(let n of d.errors)c&&_r(n.message,dr)||t.push({where:e,message:n.message,source:n.source,severity:`error`});for(let n of d.warnings)t.push({where:e,message:n.message,source:n.source,severity:`warning`});s(e,n,a)},u=(e,t)=>{let n=cr(t);if(!n)return null;let r=gr(e,n);return r?{...r,source:n}:null},d=(e,n)=>{if(n==null)return{refused:!1};let r=re(n);if(r)return t.push({where:e,message:r.message,source:r.source,severity:`error`}),{refused:!0};let i=gt(`predicate`,n);for(let n of i.errors)t.push({where:e,message:n.message,source:n.source,severity:`error`});for(let n of i.warnings)t.push({where:e,message:n.message,source:n.source,severity:`warning`});return{refused:!1}},f=(e,n)=>{if(n==null)return;let r=cr(n)??``,i=Ce.safeParse(n);if(!i.success){for(let n of i.error.issues)t.push({where:e,message:n.message,source:r,severity:`error`});return}let a=gt(`value`,n);for(let n of a.errors)t.push({where:e,message:`${We} ${n.message}`,source:n.source,severity:`error`});for(let n of a.warnings)t.push({where:e,message:n.message,source:n.source,severity:`warning`})};for(let n of w(e.flows)){let e=typeof n.name==`string`?n.name:`(unnamed flow)`,i=w(n.nodes),a=i.find(e=>e.type===`start`)?.config??{},o=typeof a.objectName==`string`?a.objectName:void 0,s=me({...n,nodes:i}),c=An(n,s),u=(e,n)=>{if(!o)return;let i=cr(n);if(i)for(let n of Nn(i,c,r.get(o)??[]))t.push({where:e,message:Pn(n,o),source:i,severity:`warning`})},p=(e,n)=>{if(n==null)return{refused:!1};let r=ze(n);return r?(t.push({where:e,message:r.message,source:r.source,severity:`error`}),{refused:!0}):{refused:!1}};for(let n of s){let r=n.scope?`flow '${e}' \xB7 ${n.scope}`:`flow '${e}'`;for(let e of w(n.nodes)){let n=e.config??{},i=`${r} \xB7 node '${e.id}' (${e.type}) condition`;p(i,n.condition).refused||(l(i,n.condition,o),u(i,n.condition));let a=typeof e.type==`string`?e.type:``;for(let t of Be(a,n)){let n=`${r} \xB7 node '${e.id}' (${a}) ${t.entry.label} at config.${t.path}`;if(t.entry.role===`value`){f(n,t.value);continue}t.entry.role===`predicate`&&(d(n,t.value).refused||u(n,t.value))}if(e.type===`script`){let i=(typeof n.function==`string`?n.function.trim():``)||(typeof n.functionName==`string`?n.functionName.trim():``),a=typeof n.actionType==`string`?n.actionType.trim():``,o=[`actionType`,`template`,`recipients`,`variables`,`script`].filter(e=>n[e]!=null);o.length>0?t.push({where:`${r} \xB7 node '${e.id}' (script) callable`,message:`script node carries \`${o.map(e=>`config.${e}`).join("`, `")}\` \u2014 retired in @objectstack/spec 17 (#4343). The built-in 'email'/'slack' actions were logger-backed stubs that delivered nothing, and inline \`config.script\` was never executed. `+(a&&a!==`invoke_function`&&![`email`,`slack`].includes(a)?`\`actionType: '${a}'\` named a registered function \u2014 move it to \`function: '${a}'\`. `:"Use a `notify` node for mail, a `connector_action` (Slack connector) or `http` node for Slack, and a registered function for logic. ")+"Run `os migrate meta --from 16` to list the mechanical edits for existing sources; apply them by hand.",source:JSON.stringify({id:e.id,type:e.type,config:n})}):i||t.push({where:`${r} \xB7 node '${e.id}' (script) callable`,message:"script node declares no `function` — it would do nothing at runtime. Name a registered function (`function: 'my_fn'`, registered via `defineStack({ functions })`).",source:JSON.stringify({id:e.id,type:e.type,config:n})})}}for(let e of n.edges){let t=`${r} \xB7 edge '${e.id}' (${e.source}\u2192${e.target}) condition`;p(t,e.condition).refused||(l(t,e.condition,o),u(t,e.condition))}}}for(let e of n){let n=typeof e.name==`string`?e.name:void 0,a=e.validations;for(let e of w(a)){let t=`object '${n}' \xB7 validation '${e.name??`?`}'`;l(t,e.condition,n,`record`),l(`${t} when`,e.when,n,`record`);for(let t of lr(e,``))c(`object '${n}' \xB7 ${t.label}`,t.label,t.raw,n)}let o=e.fields,d=Array.isArray(o)?o.filter(e=>!!e&&typeof e==`object`).map(e=>[typeof e.name==`string`?e.name:`?`,e]):o&&typeof o==`object`?Object.entries(o).filter(([,e])=>!!e&&typeof e==`object`).map(([e,t])=>[e,t]):[],f=sr(e);for(let[e,a]of d){for(let r of[`requiredWhen`,`readonlyWhen`,`conditionalRequired`,`visibleWhen`]){let i=`object '${n}' \xB7 field '${e}' ${r}`,o=a[r],s=u(r,o);l(i,o,n,`record`,s!==null),s&&t.push({where:i,message:s.message,source:s.source,severity:`error`})}for(let[t,r]of w(a.options).entries())l(`object '${n}' \xB7 field '${e}' option ${typeof r.value==`string`?`'${r.value}'`:`#${t}`} visibleWhen`,r.visibleWhen,n,`record`);for(let[r,i,o]of[[`readonlyWhen`,a.readonlyWhen,`the field would be locked on every write`],[`requiredWhen`,a.requiredWhen,`the requirement would never be enforced — the predicate faults, the server logs and skips it, and the field stays optional in the database`]]){let a=cr(i);f!==1&&a&&or(a)&&t.push({where:`object '${n}' \xB7 field '${e}' ${r}`,message:`\`${r}\` reads \`parent\`, but object '${n}' declares ${f===0?`no`:`${f}`} \`master_detail\` relationship${f===1?``:`s`} \u2014 so the server has no header record to bind as \`parent\` and ${o}. `+(f===0?"Declare the owning relationship as `Field.masterDetail('<master>')`, or rewrite the predicate against `record`.":"`parent` needs exactly one master; name the header explicitly through `record.<fk>` state instead, or model the extra relationship as a `lookup`."),source:a,severity:`error`})}if(c(`object '${n}' \xB7 field '${e}' requiredWhen`,`field '${e}' requiredWhen`,a.requiredWhen,n,`fail-open`),a.expression){let o=gt(`value`,a.expression,n?{objectName:n,fields:r.get(n),fieldTypes:i.get(n),scope:`record`}:{scope:`record`}),c=`object '${n}' \xB7 field '${e}' expression`;for(let e of o.errors)t.push({where:c,message:e.message,source:e.source,severity:`error`});for(let e of o.warnings)t.push({where:c,message:e.message,source:e.source,severity:`warning`});s(c,a.expression,n)}}}let p=new Set,m=(e,t,n)=>{let r=n??(typeof t.objectName==`string`?t.objectName:void 0),i=typeof t.name==`string`?t.name:`?`,a=`${r??``}:${i}`;p.has(a)||(p.add(a),l(`${e} \xB7 action '${i}' visible`,t.visible,r,`record`),typeof t.disabled!=`boolean`&&l(`${e} \xB7 action '${i}' disabled`,t.disabled,r,`record`))};for(let t of w(e.actions))m(`stack`,t);for(let e of n){let t=typeof e.name==`string`?e.name:void 0;for(let n of w(e.actions))m(`object '${t}'`,n,t)}for(let t of w(e.sharingRules)){let e=typeof t.object==`string`?t.object:void 0;l(`sharingRule '${t.name??`?`}'${e?` (${e})`:``} condition`,t.condition,e,`record`)}for(let n of w(e.hooks)){let e=n.name??`?`;if(typeof n.object==`string`){l(`hook '${e}' (${n.object}) condition`,n.condition,n.object,`record`),c(`hook '${e}' (${n.object}) condition`,`hook '${e}' condition`,n.condition,n.object);continue}let r=Array.isArray(n.object)?n.object.filter(e=>typeof e==`string`&&e!==`*`):[];if(r.length===0){l(`hook '${e}' condition`,n.condition,void 0,`record`);continue}let i=t.length,a=new Set,o=[];for(let i of r){let r=t.length;l(`hook '${e}' (${i}) condition`,n.condition,i,`record`),c(`hook '${e}' (${i}) condition`,`hook '${e}' condition`,n.condition,i);for(let e=r;e<t.length;e++){let n=t[e],r=`${n.message}\0${n.source??``}`;a.has(r)||(a.add(r),o.push(n))}}t.length=i,t.push(...o)}return t}function yr(e,t,n,r){let i=e.createSourceFile(t,n,r.target,r.setParentNodes,r.scriptKind),a=i.parseDiagnostics;if(!a||a.length===0)return{sourceFile:i};let o=a[0],{line:s,character:c}=i.getLineAndCharacterOfPosition(o.start??0),l=r.synthesizedLinesBefore??0;return{sourceFile:i,failure:{message:e.flattenDiagnosticMessageText(o.messageText,` `),line:Math.max(1,s+1-l),column:c+1,count:a.length}}}function br(e){let t=e.count>1?`; ${e.count} syntax errors in total`:``;return`line ${e.line}, column ${e.column}: ${e.message}${t}`}var xr=`The source is parsed (never executed) so it can be checked. A source with syntax errors is only partially recovered, so the checks that follow may have skipped real problems — fix the syntax error and re-run to get a verdict that covers the whole source.`,Sr=null;function Cr(){if(Sr)return Sr;let e=import.meta.url?import.meta.url:typeof __filename<`u`?__filename:process.cwd()+`/`;try{Sr=(0,C.createRequire)(e)(`typescript`)}catch(e){throw Error(`@objectstack/lint: checking plugin source for startup registry verdicts requires the "typescript" package, which could not be loaded (${e instanceof Error?e.message:String(e)}). It is a declared dependency of @objectstack/lint \u2014 if this deployment prunes packages, keep "typescript" in the image; it is only loaded when plugin source is actually checked.`)}return Sr}var wr=`startup-open-vocabulary-verdict`,Tr=`startup-verdict-assertive-wording`,Er=`startup-source-unparseable`,Dr=new Map([[`getRegisteredNodeTypes`,`ADR-0018 keeps the flow node-type vocabulary open and runtime-extensible — a plugin registers its executor from its own init()/start(), which can be after this line (#4771)`],[`knownNodeTypes`,`ADR-0018 keeps the flow node-type vocabulary open and runtime-extensible — a plugin registers its executor from its own init()/start(), which can be after this line (#4771)`],[`getUnknownNodeTypeAudit`,`the unknown-node-type audit is a snapshot of an OPEN vocabulary a plugin can still extend during boot; it is read-only by design and answers "unknown as of now", never "unknown for this deployment" (#4771)`],[`getActionDescriptors`,`ADR-0018 action descriptors are published by plugins during boot, so a type missing from them here means "not published YET" (#4771)`],[`getRegisteredExecutors`,`executors are contributed by plugins during boot — an executor missing here may simply be a plugin that has not started`],[`listExecutors`,`executors are contributed by plugins during boot — an executor missing here may simply be a plugin that has not started`],[`getRegisteredTools`,`AI tools are contributed by plugins during boot, so the registered set is not final until every plugin has started`],[`listConnectors`,`connectors are contributed by plugins during boot (StackSchema.connectors documents provider-bound instances registered by plugins), so the list is not final until every plugin has started`],[`getRegisteredConnectors`,`connectors are contributed by plugins during boot, so the registered set is not final until every plugin has started`],[`listCapabilities`,`ADR-0066 capabilities are declared by every installed package, so the set is not final until every plugin has contributed its declarations`],[`getRegisteredCapabilities`,`ADR-0066 capabilities are declared by every installed package, so the set is not final until every plugin has contributed its declarations`],[`listProviders`,`providers are contributed by plugins during boot — a provider missing here may simply be a plugin that has not started`],[`getRegisteredProviders`,`providers are contributed by plugins during boot — a provider missing here may simply be a plugin that has not started`]]),Or=new Map([[`constructor`,`the constructor runs at composition time — before ANY plugin has been initialized`],[`init`,`another plugin's init() may not have run yet (ADR-0116), so the vocabulary is still filling`],[`start`,`sibling plugins' start() have not all run, and ADR-0018 lets a plugin register its contributions from start() — the vocabulary is still filling`]]),kr=[`seal`],Ar=new Set([`warn`,`error`,`fatal`]),jr=new Set([`warn`,`error`,`fatal`,`info`,`debug`,`trace`,`log`]),Mr=new Set([`insert`,`insertOne`,`update`,`updateOne`,`upsert`,`save`,`saveMetaItem`]),Nr=[`will fail`,`fails at execution`,`nothing will register`,`no plugin provides`,`is not installed`,`is not configured`,`you need`,`you must install`,`must be provisioned`],Pr=[`not yet`,`yet been registered`,`so far`,`as of`,`may still`,`might still`,`still be registered`,`has started`,`have started`],Fr='Take one of the three shapes the fixes took: (1) resolve where the value is USED, not where you start — a lazy accessor or a `kernel:ready`/`kernel:bootstrapped` hook sees a provider that registered later (`createLazyCacheRateLimitStorage()` in plugin-auth, #4772); (2) seal the vocabulary, then judge — have the host declare the moment it can no longer grow and draw the conclusion there (`AutomationEngine.sealNodeTypeVocabulary()`, called at `kernel:bootstrapped`, #4771); (3) order the verdict AFTER the mutation it describes, so it cannot attest to a state this same boot goes on to contradict (the ADR-0104 attestation, #4769). If the conclusion must stay here, keep the two worlds apart in the wording: "no executor registered YET (as of plugin start)" is true; "will fail at execution time" is a claim about a world that has not finished forming.';function Ir(e,t){return e.isFunctionDeclaration(t)||e.isFunctionExpression(t)||e.isArrowFunction(t)||e.isMethodDeclaration(t)||e.isConstructorDeclaration(t)||e.isGetAccessorDeclaration(t)||e.isSetAccessorDeclaration(t)}function Lr(e,t,n){t.forEachChild(t=>{Ir(e,t)||e.isClassDeclaration(t)||e.isClassExpression(t)||(n(t),Lr(e,t,n))})}function Rr(e,t,n){t.forEachChild(t=>{n(t),Rr(e,t,n)})}function zr(e,t){if(!e.isCallExpression(t))return;let n=t.expression;if(e.isIdentifier(n))return n.text;if(e.isPropertyAccessExpression(n)&&e.isIdentifier(n.name))return n.name.text}function Br(e,t){if(!e.isCallExpression(t))return;let n=t.expression;if(!e.isPropertyAccessExpression(n)||!e.isIdentifier(n.name))return;let r=n.name.text;if(!jr.has(r))return;let i=n.expression,a;if(e.isIdentifier(i)?a=i.text:e.isPropertyAccessExpression(i)&&e.isIdentifier(i.name)&&(a=i.name.text),a)return/^(logger|log|console)$/i.test(a)?r:void 0}function Vr(e,t){let n=[],r=t=>{(e.isStringLiteralLike(t)||e.isTemplateHead(t)||e.isTemplateMiddle(t)||e.isTemplateTail(t))&&n.push(t.text)};return r(t),Rr(e,t,r),n.join(` `).toLowerCase()}function Hr(e,t){let n=!1,r=t=>{if(!n&&e.isIdentifier(t)){let e=t.text.toLowerCase();kr.some(t=>e.includes(t))&&(n=!0)}};return r(t),Rr(e,t,r),n}function Ur(e,t){let n=new Set;for(let r of t.statements)if(e.isVariableStatement(r)&&!(r.declarationList.flags&e.NodeFlags.Const))for(let t of r.declarationList.declarations)e.isIdentifier(t.name)&&n.add(t.name.text);return n}function Wr(e,t){let n=new Map;return Rr(e,t,t=>{e.isFunctionDeclaration(t)&&t.name&&t.body||e.isMethodDeclaration(t)&&e.isIdentifier(t.name)&&t.body?n.set(t.name.text,t.body):e.isVariableDeclaration(t)&&e.isIdentifier(t.name)&&t.initializer&&(e.isArrowFunction(t.initializer)||e.isFunctionExpression(t.initializer))&&t.initializer.body&&n.set(t.name.text,t.initializer.body)}),n}function Gr(e,t){let n=[],r=t=>{let r=[],i=!1;for(let n of t.members)e.isMethodDeclaration(n)&&e.isIdentifier(n.name)?(n.name.text===`init`||n.name.text===`start`)&&(i=!0):e.isPropertyDeclaration(n)&&e.isIdentifier(n.name)&&(n.name.text===`init`||n.name.text===`start`)&&n.initializer&&(e.isArrowFunction(n.initializer)||e.isFunctionExpression(n.initializer))&&(i=!0);if(i){for(let n of t.members)e.isConstructorDeclaration(n)&&n.body?r.push({phase:`constructor`,body:n.body}):e.isMethodDeclaration(n)&&e.isIdentifier(n.name)&&n.body?Or.has(n.name.text)&&r.push({phase:n.name.text,body:n.body}):e.isPropertyDeclaration(n)&&e.isIdentifier(n.name)&&Or.has(n.name.text)&&n.initializer&&(e.isArrowFunction(n.initializer)||e.isFunctionExpression(n.initializer))&&n.initializer.body&&r.push({phase:n.name.text,body:n.initializer.body});r.length&&n.push({label:t.name?.text??`<anonymous class>`,phases:r})}},i=t=>{let r=[],i,a=!1;for(let n of t.properties){if(!e.isPropertyAssignment(n)||!e.isIdentifier(n.name))continue;let t=n.name.text;t===`name`&&e.isStringLiteralLike(n.initializer)&&(i=n.initializer.text),(t===`init`||t===`start`)&&Ir(e,n.initializer)&&(a=!0),Or.has(t)&&(e.isArrowFunction(n.initializer)||e.isFunctionExpression(n.initializer))&&n.initializer.body&&r.push({phase:t,body:n.initializer.body})}i&&a&&r.length&&n.push({label:`${i} (object plugin)`,phases:r})};return Rr(e,t,t=>{e.isClassDeclaration(t)||e.isClassExpression(t)?r(t):e.isObjectLiteralExpression(t)&&i(t)}),n}function Kr(e,t={}){if(!e||!e.trim())return[];let n=!1;for(let t of Dr.keys())if(e.includes(t)){n=!0;break}if(!n)return[];let r=Cr(),i=t.file??`source`,{sourceFile:a,failure:o}=yr(r,i,e,{target:r.ScriptTarget.Latest,setParentNodes:!0,scriptKind:r.ScriptKind.TS}),s=[];o&&s.push({severity:`warning`,rule:Er,where:i,path:`${i}:${o.line}`,message:`source did not parse (${br(o)}), so this rule read a partially recovered tree \u2014 a startup verdict in the unread part is not reported.`,hint:xr});let c=Ur(r,a),l=Wr(r,a),u=e=>a.getLineAndCharacterOfPosition(e.getStart(a)).line+1;for(let e of Gr(r,a))for(let{phase:t,body:n}of e.phases){let a=[],o=new Set,d=(e,t)=>{a.push(e),!(t>=2)&&Lr(r,e,e=>{let n=zr(r,e);if(!n||o.has(n))return;let i=l.get(n);i&&(o.add(n),d(i,t+1))})};d(n,0);let f=[];for(let e of a)Lr(r,e,e=>{let t=zr(r,e);t&&Dr.has(t)&&f.push({probe:t,node:e})});if(!f.length||a.some(e=>Hr(r,e)))continue;let p=[];for(let e of a)Lr(r,e,e=>{let t=Br(r,e);if(t&&Ar.has(t)){p.push({kind:`announced`,detail:`${t} log`,line:u(e),node:e});return}let n=zr(r,e);if(n&&Mr.has(n)){p.push({kind:`persisted`,detail:`${n}()`,line:u(e),node:e});return}if(r.isBinaryExpression(e)&&e.operatorToken.kind===r.SyntaxKind.EqualsToken){let t=e.left,n;r.isPropertyAccessExpression(t)&&r.isIdentifier(t.name)?n=t.expression.kind===r.SyntaxKind.ThisKeyword?`this.${t.name.text}`:`<obj>.${t.name.text}`:r.isIdentifier(t)&&c.has(t.text)&&(n=`module-level \`${t.text}\``),n&&p.push({kind:`cached`,detail:n,line:u(e),node:e})}});if(!p.length)continue;let m=f[0],h=p[0],g=`${e.label}.${t}${t===`constructor`?``:`()`}`,_=Dr.get(m.probe),v=Or.get(t);s.push({severity:`warning`,rule:wr,where:g,path:`${i}:${u(m.node)}`,message:`\`${m.probe}()\` reads a vocabulary that is still filling, and the conclusion is recorded (${h.kind}: ${h.detail}, line ${h.line}). ${_}; ${v}. "absent" here has two meanings the recorded verdict cannot tell apart \u2014 no provider in this deployment, or a provider that registers later in this same boot \u2014 and nothing retracts the record when the second one turns out to be the case (#4771 / #4772).`,hint:Fr});for(let e of p){if(e.kind!==`announced`)continue;let t=Vr(r,e.node);if(!t||Pr.some(e=>t.includes(e)))continue;let n=Nr.find(e=>t.includes(e));n&&s.push({severity:`warning`,rule:Tr,where:g,path:`${i}:${e.line}`,message:`the diagnostic says "${n}" about a vocabulary that can still grow during this boot. #4771 printed "will fail at execution time" for eight approval flows 0.8s before the executor that runs them was registered, and a deployment that genuinely lacked the plugin printed the identical eight \u2014 so the line could not tell an operator which of the two they had. #4772's remedy ("you need Redis") sent operators to fix a problem they did not have, and connecting Redis did not change the message.`,hint:Fr})}}return s}var qr=`list-view-filters-in-views-mode`;function Jr(e,t,n,r){if(!e||typeof e!=`object`)return;let i=e;i.quickFilters!=null&&r.push({severity:`error`,rule:qr,where:t,path:`${n}.quickFilters`,message:'`quickFilters` is a page filters-mode control and is ignored on an object list view ("views" mode) — the ViewTabBar owns nav here.',hint:'Move `quickFilters` to a page list (InterfaceListPage, "filters" mode), or remove it. See ADR-0047.'});let a=i.userFilters;if(a&&typeof a==`object`){let e=a;(e.element===`tabs`||e.tabs!=null)&&r.push({severity:`error`,rule:qr,where:t,path:`${n}.userFilters`,message:'`userFilters` with `element: "tabs"` is page-only and is ignored on an object list view ("views" mode) — it would collide with the ViewTabBar.',hint:'Use `listViews` for named presets on an object (each becomes a segmented tab), switch to `element: "dropdown"` for value chips, or move the `tabs` filter to a page list (InterfaceListPage, "filters" mode). See ADR-0047.'})}}function Yr(e,t,n,r){if(e&&typeof e==`object`)for(let[i,a]of Object.entries(e))Jr(a,`${t} \u203A listViews.${i}`,`${n}.listViews.${i}`,r)}function Xr(e){let t=[];return w(e.objects).forEach((e,n)=>{let r=typeof e.name==`string`?`object "${e.name}"`:`objects[${n}]`;Yr(e.listViews,r,`objects[${n}]`,t)}),w(e.views).forEach((e,n)=>{let r=typeof e.objectName==`string`?e.objectName:typeof e.name==`string`?e.name:void 0,i=r?`view "${r}"`:`views[${n}]`;Jr(e.list,`${i} \u203A list`,`views[${n}].list`,t),Yr(e.listViews,i,`views[${n}]`,t)}),t}var Zr=e=>!!e&&typeof e==`object`&&!Array.isArray(e);function Qr(e){return Array.isArray(e)?e.flatMap((e,t)=>Zr(e)?[{name:String(e.name??t),def:e,key:`[${t}]`}]:[]):Zr(e)?Object.entries(e).flatMap(([e,t])=>Zr(t)?[{name:e,def:{name:e,...t},key:`.${e}`}]:[]):[]}function $r(e,t,n,r){for(let i of t)e.push({severity:i.severity,rule:i.rule,where:n,path:`${r}.${i.path}`,message:i.message,hint:i.fix})}function ei(e){let n=[];if(!Zr(e))return n;for(let[t,r]of Qr(e.objects).entries())for(let e of Qr(r.def.fields))$r(n,ce(e.def),`object "${r.name}" \u203A fields.${e.name}`,`objects[${t}].fields${e.key}`);let r=new Map(Qr(e.objects).map(e=>[e.name,e.def])),i=e=>typeof e==`string`&&e?e:void 0,a=e=>e?r.get(e):void 0,o=e=>Zr(e.data)?i(e.data.object):void 0,s=(e,t)=>a(o(e)??i(t.objectName)??i(t.object));for(let[r,i]of Qr(e.views).entries()){let e=i.def.object?`view container "${i.name}"`:`view container [${r}]`;Zr(i.def.list)&&$r(n,t(i.def.list,s(i.def.list,i.def)),`${e} \u203A list`,`views[${r}].list`);for(let a of Qr(i.def.listViews))$r(n,t(a.def,s(a.def,i.def)),`${e} \u203A listViews.${a.name}`,`views[${r}].listViews${a.key}`)}for(let[r,i]of Qr(e.objects).entries()){let e=`object "${i.name}"`;Zr(i.def.list)&&$r(n,t(i.def.list,a(o(i.def.list)??i.name)),`${e} \u203A list`,`objects[${r}].list`);for(let s of Qr(i.def.listViews))$r(n,t(s.def,a(o(s.def)??i.name)),`${e} \u203A listViews.${s.name}`,`objects[${r}].listViews${s.key}`)}for(let t of Qr(e.webhooks))$r(n,je(t.def),`webhook "${t.name}"`,`webhooks${t.key}`);return n}var ti=`object/managed-api-method-unaffordable`,ni=e=>!!e&&typeof e==`object`&&!Array.isArray(e);function ri(e){return Array.isArray(e)?e.flatMap((e,t)=>ni(e)?[{name:String(e.name??t),def:e,key:`[${t}]`}]:[]):ni(e)?Object.entries(e).flatMap(([e,t])=>ni(t)?[{name:e,def:{name:e,...t},key:`.${e}`}]:[]):[]}function ii(e){let t=[];if(!ni(e))return t;for(let[n,r]of ri(e.objects).entries()){let e=v(r.def);if(e.length===0)continue;let i=e.map(e=>e.verb).join(`, `),a=[...new Set(e.map(e=>e.needs))];t.push({severity:`error`,rule:ti,where:`object "${r.name}"`,path:`objects[${n}].enable.apiMethods`,message:`\`managedBy: '${String(r.def.managedBy)}'\` object "${r.name}" `+qe(e)+` The registry STRIPS [${i}] at registration, so this declaration and the API you actually get already disagree \u2014 today the only trace is a line in the boot log.`,hint:`Either add \`userActions: { ${a.map(e=>`${e}: true`).join(`, `)} }\` to the object \u2014 only if the write is genuinely one a user context may perform, and only once the guard enforcing it exists (ADR-0092 D4: affordance never ships ahead of the guard) \u2014 or remove [${i}] from \`enable.apiMethods\`, which is what the runtime does for you today.`})}return t}var ai=`flow-trigger-unknown-object`,oi=`flow-draft-status-ambiguous`,si=`flow-trigger-unknown-event`,ci=`flow-time-relative-descriptor-invalid`,li=`flow-time-relative-descriptor-unroutable`,ui=`flow-trigger-unroutable`,di=/^record-(?:before|after)-(?:create|insert|update|delete|write)$/;function fi(e){let t=typeof e;return t===`string`||t===`number`||t===`boolean`?`${JSON.stringify(e)} (a ${t})`:t===`bigint`?`${String(e)}n (a bigint)`:`a ${t}`}function pi(e){if(typeof e==`string`)return`'${e}'`;let t=JSON.stringify(e);return t===void 0?`a ${typeof e}`:t}function mi(e){let t=Array.isArray(e.nodes)?e.nodes:[],n=t.findIndex(e=>e?.type===`start`);return n>=0?{node:t[n],index:n}:void 0}function hi(e){let t=[],n=w(e.flows);if(n.length===0)return t;let i=new Set(w(e.objects).map(e=>typeof e.name==`string`?e.name:void 0).filter(e=>!!e));return n.forEach((e,n)=>{let a=typeof e.name==`string`?e.name:`#${n}`,o=mi(e),s=o?.node.config??{},c=typeof s.triggerType==`string`?s.triggerType:void 0,l=!!c&&c.startsWith(`record-`),u=Array.isArray(s.triggerType)&&s.triggerType.some(e=>typeof e==`string`&&e.startsWith(`record-`)),d=s.timeRelative!=null&&typeof s.timeRelative==`object`,f=r(e)!==void 0;if(l&&o){let e=typeof s.objectName==`string`?s.objectName:void 0;e&&!i.has(e)&&!e.startsWith(`sys_`)&&t.push({severity:`warning`,rule:ai,where:`flow "${a}" \u203A start node`,path:`flows[${n}].nodes[${o.index}].config.objectName`,message:`targets object '${e}', which this stack does not define \u2014 if the name is wrong, the flow will never fire (and the runtime stays silent about it).`,hint:`Object names match exactly. Check config.objectName against the object's registered name (e.g. 'app_candidate', not 'candidate'). If the object comes from another installed package, this warning can be ignored.`})}if(d&&o){let e=s.timeRelative,r=typeof e.object==`string`?e.object:void 0;r&&!i.has(r)&&!r.startsWith(`sys_`)&&t.push({severity:`warning`,rule:ai,where:`flow "${a}" \u203A start node`,path:`flows[${n}].nodes[${o.index}].config.timeRelative.object`,message:`sweeps object '${r}', which this stack does not define \u2014 if the name is wrong, the sweep will match nothing (and the runtime stays quiet about it).`,hint:`Object names match exactly. Check config.timeRelative.object against the object's registered name. If the object comes from another installed package, this warning can be ignored.`});let c=mt.safeParse(e);if(!c.success){let e=c.error.issues.map(e=>`${e.path.join(`.`)||`(root)`}: ${e.message.replace(/\s+/g,` `).trim()}`).join(`; `);t.push({severity:`error`,rule:ci,where:`flow "${a}" \u203A start node`,path:`flows[${n}].nodes[${o.index}].config.timeRelative`,message:`has a config.timeRelative descriptor the time-relative trigger REFUSES at bind time, so the sweep is never installed \u2014 the flow declares a time-relative trigger and then never runs (the only trace is one warn in the server log). ${e}`,hint:`Those messages are TimeRelativeTriggerSchema's own — the same schema the trigger safeParses at bind time, so a descriptor that satisfies them binds. An unrecognized key names the declared key it was probably meant to be; see content/docs/references/automation/time-relative-trigger.mdx.`})}}if(o&&l&&!di.test((c??``).trim())&&t.push({severity:`error`,rule:si,where:`flow "${a}" \u203A start node`,path:`flows[${n}].nodes[${o.index}].config.triggerType`,message:`triggerType '${c}' is not a recognized record trigger \u2014 the flow binds to the record-change trigger but never fires (the runtime stays silent about it).`,hint:`Use record-{before,after}-{create,update,delete,write}. 'write' fires on create OR update in one flow (#3427); create/insert are synonyms. There is no "any change" token — pick the specific event(s).`}),o&&u&&t.push({severity:`error`,rule:si,where:`flow "${a}" \u203A start node`,path:`flows[${n}].nodes[${o.index}].config.triggerType`,message:`triggerType is an array (${JSON.stringify(s.triggerType)}), which is not supported \u2014 a start node takes a single trigger event, so the flow binds to nothing and never fires (the runtime stays silent about it).`,hint:`Use one triggerType string. For "created or updated" use record-after-write (one flow, both events, #3427). For any other combination, author one flow per event — multi-event arrays are deferred (#3457).`}),o&&s.timeRelative!=null&&typeof s.timeRelative!=`object`){let r=l||u?`its record-change trigger`:s.schedule!=null||e.type===`schedule`?"its plain `config.schedule` cadence":c===`api`||e.type===`api`?`its api trigger`:void 0,i=r?`The flow still binds through ${r}, so the descriptor is silently DROPPED \u2014 it fires on that trigger's terms (once per firing, with no record on the context) instead of once per matching record, and nothing anywhere reports the difference.`:`Nothing else on this start node declares a trigger either, so the flow binds to NOTHING and never fires — with zero diagnostics at any layer, not even the one bind-time warn a descriptor that IS an object gets when the trigger refuses it.`;t.push({severity:`error`,rule:li,where:`flow "${a}" \u203A start node`,path:`flows[${n}].nodes[${o.index}].config.timeRelative`,message:`has config.timeRelative = ${fi(s.timeRelative)}, which is not the descriptor OBJECT this slot takes \u2014 the engine routes a flow to the time-relative sweep only when config.timeRelative is an object, so this one is never routed there and the sweep is never installed. ${i}`,hint:`config.timeRelative describes WHICH records to sweep — an object: { object, dateField, and exactly one of withinDays | offsetDays } (plus optional filter / maxRecords). A cadence like 'daily' is not a descriptor: HOW OFTEN the sweep runs is the sibling key config.schedule on the same start node (it defaults to daily, so it is usually omitted). See TimeRelativeTriggerSchema and content/docs/references/automation/time-relative-trigger.mdx.`})}let p=l||u||d||s.schedule!=null||e.type===`schedule`||e.type===`api`||c===`api`;if(o&&e.type===`record_change`&&!p){let e=s.triggerType!=null;t.push({severity:`error`,rule:ui,where:`flow "${a}" \u203A start node`,path:`flows[${n}].nodes[${o.index}].config.triggerType`,message:`declares type: 'record_change' but `+(e?`its start node's triggerType is ${pi(s.triggerType)}, which the engine routes to NO trigger`:`its start node has no triggerType at all, so there is nothing for the engine to route`)+` — it binds a record-change flow only for a token starting with 'record-', so this flow is demoted to a manual one and never fires. Nothing NAMES it: the unbound-flow audit resolves the same binding and skips the flow as "manual — nothing to bind", so neither the boot warning nor the startup summary lists it; the only trace is the banner's flow count being one higher than its bound count.`,hint:`Use record-{before,after}-{create,update,delete,write} ('write' is create OR update in one flow, #3427; create/insert are synonyms). If the flow really is launched by hand or from a screen, declare type: 'autolaunched' or 'screen' instead of 'record_change' — those types have no trigger to be missing.`})}f&&(e.status==null||e.status===`draft`)&&t.push({severity:`warning`,rule:oi,where:`flow "${a}"`,path:`flows[${n}].status`,message:`has status 'draft' (the default when none is authored). Draft flows DO still fire their triggers (only 'obsolete'/'invalid' disable), so the intent is ambiguous.`,hint:`Declare status: 'active' to arm it deliberately, or status: 'obsolete' to disable it.`})}),t}function gi(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function _i(e){return typeof e==`string`&&e.length>0?e:void 0}var vi=new Map([...Ee].map(([e,t])=>[e,t.map(e=>e.key)])),yi=16;function bi(e,t){return _i(e.label)??_i(e.id)??`#${t}`}var xi=[];function Si(e){let t=_i(e);return(t?vi.get(t):void 0)??xi}function Ci(e,t){if(!gi(e))return;let n=t instanceof Set?t:new Set(t);if(n.size===0)return e;let r;for(let t of Object.keys(e))n.has(t)&&(r??={...e},delete r[t]);return r??e}function wi(e,t){let n=[];if(!gi(e))return n;let r=(e,t,i,a)=>{!Array.isArray(e)||a>yi||e.forEach((e,o)=>{if(!gi(e))return;let s=`${t}[${o}]`,c=Si(e.type);n.push({node:e,path:s,localConfig:Ci(e.config,c),regionTrail:i,depth:a});let l=_i(e.type),u=c.length>0?c:void 0;if(!u||!gi(e.config))return;let d=e.config,f=`${l} "${bi(e,o)}"`;for(let e of u){let t=d[e];if(e===`branches`){if(!Array.isArray(t))continue;t.forEach((e,t)=>{if(!gi(e))return;let n=_i(e.name)??`#${t}`;r(e.nodes,`${s}.config.branches[${t}].nodes`,Ti(i,`${f} \u203A branch ${n}`),a+1)});continue}gi(t)&&r(t.nodes,`${s}.config.${e}.nodes`,Ti(i,`${f} \u203A ${e}`),a+1)}})};return r(e.nodes,`${t}.nodes`,``,0),n}function Ti(e,t){return e?`${e} \u203A ${t}`:t}var Ei=`flow-template-unknown-field`,Di=`flow-template-lookup-traversal`,Oi=`flow-template-field-unprovisioned`,ki=new Set([...bt,`name`,`owner`,`record_type`]),Ai=new Set([`lookup`,`master_detail`,`user`,`tree`]),ji=new Set([`get_record`,`update_record`,`delete_record`]);function Mi(e){let t=new Map;for(let n of w(e.fields))typeof n.name==`string`&&t.set(n.name,typeof n.type==`string`?n.type:``);return t}function Ni(e){let t=[],n=/\{([^{}]+)\}/g,r;for(;(r=n.exec(e))!==null;){let e=r[1].trim();if(!/^[A-Za-z_$][\w$]*(?:\.(?:[A-Za-z_$][\w$]*|\d+))*$/.test(e))continue;let n=e.split(`.`);if(n[0]!==`record`)continue;let i=n.slice(1);i.length>0&&t.push(i)}return t}function Pi(e,t){if(typeof e==`string`){e.includes(`{`)&&t.push(e);return}if(Array.isArray(e)){for(let n of e)Pi(n,t);return}if(e&&typeof e==`object`)for(let n of Object.values(e))Pi(n,t)}var Fi=[`config`,`notify`,`update_record`,`create_record`,`http`,`script`,`screen`,`wait`,`approval`,`connector_action`,`subflow`,`decision`,`start`];function Ii(e,t){let n=[],r=[];for(let i of Fi){if(!(i in e))continue;let a=e[i];if(t&&a&&typeof a==`object`&&!Array.isArray(a)){let{filter:e,...t}=a,i=[];Pi(e,i);for(let e of i)n.push({text:e,inFilter:!0});let o=[];Pi(t,o);for(let e of o)r.push({text:e,inFilter:!1});continue}let o=[];Pi(a,o);for(let e of o)r.push({text:e,inFilter:!1})}return[...n,...r]}function Li(e,t){if(e.type===`record_change`)return!0;let n=typeof t.triggerType==`string`?t.triggerType:void 0;return!!n&&n.startsWith(`record-`)}function Ri(e){let t=w(e.nodes).find(e=>e.type===`start`);if(!t)return;let n=t.config??{},r=t.start??{},i=typeof n.objectName==`string`?n.objectName:void 0,a=typeof r.objectName==`string`?r.objectName:void 0;return i??a}function zi(e){let t=(w(e.nodes).find(e=>e.type===`start`)?.config??{}).expand;return typeof t==`string`?new Set(t?[t]:[]):Array.isArray(t)?new Set(t.filter(e=>typeof e==`string`&&e.length>0)):new Set}function Bi(e){let t=[],n=w(e.flows);if(n.length===0)return t;let r=new Map;for(let t of w(e.objects))typeof t.name==`string`&&r.set(t.name,t);return n.forEach((e,n)=>{let i=typeof e.name==`string`?e.name:`#${n}`;if(!Li(e,w(e.nodes).find(e=>e.type===`start`)?.config??{}))return;let a=Ri(e);if(!a)return;let o=r.get(a);if(!o)return;let s=Mi(o),c=St(o),l=zi(e);wi(e,`flows[${n}]`).forEach(({node:e,path:n,regionTrail:r,localConfig:o},u)=>{let d=typeof e.type==`string`?e.type:typeof e.id==`string`?e.id:`#${u}`,f=r?`flow "${i}" ${r} node "${d}"`:`flow "${i}" node "${d}"`,p=typeof e.type==`string`?e.type:``,m=ji.has(p),h=Ii(o!==void 0&&o!==e.config?{...e,config:o}:e,m);if(h.length===0)return;let g=new Set,_=new Set,v=new Set;for(let e of h){let r=e.inFilter;for(let i of Ni(e.text)){let e=i[0],o=i.length>1&&!/^\d+$/.test(i[1]),u=s.has(e)||ki.has(e);if(c.has(e)&&(v.has(e)||(v.add(e),t.push({severity:`warning`,rule:Oi,where:f,path:n,message:(r?`${p} filter references `:`template references `)+`'{record.${i.join(`.`)}}', and ${Tt(a,e)} \u2014 `+(r?`the token resolves to nothing on every run, which DROPS the condition from the query instead of narrowing it; the node then refuses to run at execution time (#3810).`:`the token resolves to an empty string on every run (silently).`),hint:Et(a,e)}))),!u){if(g.has(e))continue;g.add(e),t.push({severity:r?`error`:`warning`,rule:Ei,where:f,path:n,message:r?`${p} filter references '{record.${i.join(`.`)}}', but '${e}' is not a field on object '${a}' \u2014 the token resolves to nothing, which DROPS the condition from the query instead of narrowing it. The node refuses to run at execution time (#3810).`:`template references '{record.${i.join(`.`)}}', but '${e}' is not a field on object '${a}' \u2014 it resolves to an empty string at runtime (silently).`,hint:r?`Check the field name against the object's field definitions (e.g. '{record.full_name}', not '{record.full_naem}'); system columns like id/created_at/owner are also addressable. This gates the build rather than warning: an absent condition WIDENS the query, so the runtime has already decided to refuse this node.`:`Check the field name against the object's field definitions (e.g. '{record.full_name}', not '{record.full_naem}'). System columns like id/created_at/owner are also addressable.`});continue}if(o){let o=s.get(e)??``;if(Ai.has(o)&&!l.has(e)){let s=i.join(`.`);if(_.has(s))continue;_.add(s),t.push({severity:r?`error`:`warning`,rule:Di,where:f,path:n,message:r?`${p} filter references '{record.${s}}', a cross-object hop through the ${o} field '${e}' \u2014 the flow record carries '${e}' as a scalar id, not an expanded object, so the token resolves to nothing and the condition is DROPPED from the query instead of narrowing it. The node refuses to run at execution time (#3810).`:`template references '{record.${s}}', a cross-object hop through the ${o} field '${e}' \u2014 the flow record carries '${e}' as a scalar id, not an expanded object, so this resolves to an empty string at runtime (silently).`,hint:r?`Opt in to resolve it: add '${e}' to the start node's config.expand (#3475) and the engine re-reads it as the run's identity. Otherwise filter on the foreign-key id directly ('{record.${e}}'), or project the value via a formula field on '${a}'. This gates the build rather than warning: an absent condition WIDENS the query.`:`Opt in to resolve it: add '${e}' to the start node's config.expand (#3475) and the engine re-reads it as the run's identity. Otherwise reference the foreign-key id directly ('{record.${e}}'), or project the value via a formula field on '${a}'.`})}}}}})}),t}var Vi=`flow-update-readonly-field`,Hi=`flow-update-readonly-when-field`,Ui=`create_record`,Wi=new Set([`update_record`,Ui]);function Gi(e){let t=new Map;for(let n of e){let e=typeof n.name==`string`?n.name:void 0;if(!e)continue;let r=new Map,i=(e,t)=>{let n=t?.readonlyWhen,i=n!=null&&(typeof n!=`string`||n.trim()!==``);r.set(e,{readonly:t?.readonly===!0,readonlyWhen:i})},a=n.fields;if(Array.isArray(a))for(let e of a){let t=e?.name;typeof t==`string`&&i(t,e)}else if(a&&typeof a==`object`)for(let[e,t]of Object.entries(a))i(e,t);t.set(e,r)}return t}function Ki(e){let t=new Set;for(let n of e){let e=typeof n.name==`string`?n.name:void 0;e&&(n.managedBy||e.startsWith(`sys_`))&&t.add(e)}return t}function qi(e){let t=e.objectName??e.object;if(!(typeof t!=`string`||t.includes(`{`)))return t||void 0}function Ji(e){let t=[],n=w(e.flows);if(n.length===0)return t;let r=w(e.objects),i=Gi(r),a=Ki(r);return n.forEach((e,n)=>{let r=e.runAs===`user`||e.runAs===`system`?e.runAs:`user`,o=r===`system`,s=typeof e.name==`string`?e.name:`#${n}`;wi(e,`flows[${n}]`).forEach(({node:e,path:n,regionTrail:c},l)=>{let u=e?.type;if(typeof u!=`string`||!Wi.has(u))return;let d=u===Ui,f=e.config??{},p=qi(f);if(!p)return;let m=i.get(p);if(!m||d&&a.has(p))return;let h=f.fields;if(!h||typeof h!=`object`||Array.isArray(h))return;let g=bi(e,l),_=c?`flow "${s}" \u203A ${c} \u203A node "${g}"`:`flow "${s}" \u203A node "${g}"`;for(let e of Object.keys(h)){let i=m.get(e);i&&(i.readonly&&!o?t.push({severity:`error`,rule:Vi,where:_,path:`${n}.config.fields.${e}`,message:d?`writes field '${e}', which object '${p}' declares readonly:true. Under runAs:'${r}' the engine silently strips readonly fields from the INSERT payload too (the same strip the UPDATE path runs), so the row is created WITHOUT this column (it falls back to the field's defaultValue) \u2014 while the create_record step still reports success, with only a run-time warning naming the dropped field.`:`writes field '${e}', which object '${p}' declares readonly:true. Under runAs:'${r}' the engine silently strips readonly fields from the UPDATE payload (#2948), so this write never lands \u2014 while the step still reports success.`,hint:d?`Seeding a readonly column at create time is a SYSTEM act: declare the flow runAs:'system' (the intended channel \u2014 readonly governs the end-user/API surface, not trusted system writers). Otherwise remove '${e}' from this create_record node, or stamp it in a beforeInsert hook on '${p}' \u2014 a hook-assigned key is the hook's write, not a caller-supplied one, and survives the strip.`:`If automation is meant to maintain this field, declare the flow runAs:'system' (the intended channel \u2014 readonly governs the end-user/API surface, not trusted system writers). Otherwise remove '${e}' from this update_record node.`}):i.readonlyWhen&&!d&&t.push({severity:`warning`,rule:Hi,where:_,path:`${n}.config.fields.${e}`,message:`writes field '${e}', which object '${p}' declares readonlyWhen. On records where that predicate is TRUE, a runAs:'${r}' UPDATE strips the field (#3042), so this write may silently not land depending on the record's state.`,hint:`Elevation is not a workaround here: unlike the static readonly strip, the conditional lock is NOT waived by a system context, so runAs:'system' strips this field on a locked record exactly as this run does. Either confirm this node only targets records whose readonlyWhen predicate is FALSE, or derive '${e}' in a beforeUpdate hook on '${p}' - a hook-derived value is not caller-supplied and does land, even on a locked record. Otherwise remove '${e}' from this update_record node. This warning never blocks a build.`}))}})}),t}var Yi=null;function Xi(){if(Yi)return Yi;let e=import.meta.url?import.meta.url:typeof __filename<`u`?__filename:process.cwd()+`/`;try{Yi=(0,C.createRequire)(e)(`typescript`)}catch(e){throw Error(`@objectstack/lint: checking an L2 (language:'js') hook body requires the "typescript" package, which could not be loaded (${e instanceof Error?e.message:String(e)}). It is a declared dependency of @objectstack/lint \u2014 if this deployment prunes packages, keep "typescript" in the image; it is only loaded when a hook with a JS body is validated.`)}return Yi}var Zi=`hook-body-write-unknown-field`,Qi=`hook-body-source-unparseable`,$i=`hook-body-write-unprovisioned-anchor`,ea=[{id:`input-property-assign`,syntax:`ctx.input.<field> = … | ctx.input['<field>'] ⟨op⟩= …`,example:{source:`ctx.input.total = 0; ctx.input['status'] ??= 'open'; ctx.input.retries += 1;`,writes:[{field:`total`},{field:`status`},{field:`retries`}]}},{id:`input-object-assign`,syntax:`Object.assign(ctx.input, { <field>: … })`,example:{source:`Object.assign(ctx.input, { total: 5, 'status': 'open', discount });`,writes:[{field:`total`},{field:`status`},{field:`discount`}]}},{id:`record-property-assign`,syntax:`ctx.record.<field> = … | ctx.record['<field>'] ⟨op⟩= …`,example:{source:`ctx.record.stage = 'won'; ctx.record['amount'] += 1;`,writes:[{field:`stage`},{field:`amount`}]}},{id:`api-crud-literal`,syntax:`ctx.api.object('<object>').insert({…}) | .update({…}) | .updateById(id, {…})`,example:{source:`await ctx.api.object('audit_log').insert({ event: 'won' }); await ctx.api.object('crm_deal').updateById(id, { stage: 'won' });`,writes:[{field:`event`,object:`audit_log`},{field:`stage`,object:`crm_deal`}]}}],ta=[`input-property-assign`,`input-object-assign`,`api-crud-literal`],na=[{id:`record-property-assign`,reason:"a hook sandbox context has no `ctx.record` at all — `buildSandboxContext` never sets it (a hook’s record IS `ctx.input`), so the expression throws at run time rather than silently no-op’ing. A loud failure the author sees on the first run is not this advisory rule’s business"}],ra=new Set(ta),ia=new Map([[`insert`,0],[`update`,0],[`updateById`,1]]),aa=new Set([`id`,`options`,`ast`,`data`]),oa=new Set([...bt,`_id`,`name`,`space`,`owner`,`record_type`]);function sa(){return`so the value can never land: the anchor exists only in the registered schema, which is what carries it PAST the write-path validator that refuses an undeclared name outright (INVALID_FIELD). The remote database is what rejects it — on a SQL remote with an untyped driver error ('no such column') that aborts the whole statement, so the correctly named fields in the same payload never land either; on a schemaless remote the key is persisted into a column no read surface returns (#4271).`}var ca=e=>!!e&&typeof e==`object`&&!Array.isArray(e);function la(e){let t=new Map;for(let n of w(e.objects)){let e=typeof n.name==`string`?n.name:void 0;if(!e)continue;let r=new Set;for(let e of w(n.fields))typeof e.name==`string`&&e.name&&r.add(e.name);t.set(e,r)}return t}function ua(e,t){let n=e.get(t);if(n&&n.size!==0)return n}function da(e){return fa(e).writes}function fa(e){if(!/\bctx\b/.test(e)&&!/\bObject\b/.test(e))return{writes:[],ctxRecordEscapes:!1};let t=Xi(),{sourceFile:n,failure:r}=yr(t,`hook-body.ts`,`async function __body(ctx) {
|
|
2
|
-
${e}
|
|
3
|
-
}`,{target:t.ScriptTarget.Latest,setParentNodes:!1,scriptKind:t.ScriptKind.TS,synthesizedLinesBefore:1}),i=[],a=[],o=new Set,s=(e,n)=>t.isPropertyAccessExpression(e)&&t.isIdentifier(e.expression)&&e.expression.text===`ctx`&&e.name.text===n,c=(e,n)=>{if(t.isPropertyAccessExpression(e)&&t.isIdentifier(e.name)&&s(e.expression,n))return e.name.text;if(t.isElementAccessExpression(e)&&s(e.expression,n)){let n=e.argumentExpression;if(t.isStringLiteral(n)||t.isNoSubstitutionTemplateLiteral(n))return n.text}},l=e=>{if(!t.isObjectLiteralExpression(e))return[];let n=[];for(let r of e.properties)t.isPropertyAssignment(r)?(t.isIdentifier(r.name)||t.isStringLiteral(r.name))&&n.push(r.name.text):t.isShorthandPropertyAssignment(r)&&n.push(r.name.text);return n},u=e=>{if(t.isBinaryExpression(e)&&e.operatorToken.kind>=t.SyntaxKind.FirstAssignment&&e.operatorToken.kind<=t.SyntaxKind.LastAssignment){let t=c(e.left,`input`);t!==void 0&&!aa.has(t)&&i.push({patternId:`input-property-assign`,field:t});let n=c(e.left,`record`);n!==void 0&&i.push({patternId:`record-property-assign`,field:n})}if((t.isPropertyAccessExpression(e)||t.isElementAccessExpression(e))&&s(e.expression,`record`)&&o.add(e.expression),t.isBinaryExpression(e)){let n=e.operatorToken.kind;(n===t.SyntaxKind.AmpersandAmpersandToken||n===t.SyntaxKind.BarBarToken||n===t.SyntaxKind.QuestionQuestionToken)&&s(e.left,`record`)&&o.add(e.left)}if(t.isPrefixUnaryExpression(e)&&e.operator===t.SyntaxKind.ExclamationToken&&s(e.operand,`record`)&&o.add(e.operand),t.isTypeOfExpression(e)&&s(e.expression,`record`)&&o.add(e.expression),(t.isIfStatement(e)||t.isWhileStatement(e)||t.isDoStatement(e))&&s(e.expression,`record`)&&o.add(e.expression),t.isConditionalExpression(e)&&s(e.condition,`record`)&&o.add(e.condition),s(e,`record`)&&a.push(e),t.isCallExpression(e)){let n=e.expression;if(t.isPropertyAccessExpression(n)&&t.isIdentifier(n.expression)&&n.expression.text===`Object`&&n.name.text===`assign`&&e.arguments.length>=2&&s(e.arguments[0],`input`))for(let t of e.arguments.slice(1))for(let e of l(t))aa.has(e)||i.push({patternId:`input-object-assign`,field:e});if(t.isPropertyAccessExpression(n)&&t.isIdentifier(n.name)){let r=ia.get(n.name.text),a=n.expression;if(r!==void 0&&t.isCallExpression(a)&&t.isPropertyAccessExpression(a.expression)&&a.expression.name.text===`object`&&s(a.expression.expression,`api`)&&a.arguments.length===1){let o=a.arguments[0],s=t.isStringLiteral(o)||t.isNoSubstitutionTemplateLiteral(o)?o.text:void 0,c=e.arguments[r];if(s&&c!==void 0)for(let e of l(c))i.push({patternId:`api-crud-literal`,object:s,method:n.name.text,field:e})}}}t.forEachChild(e,u)};return u(n),{writes:i,ctxRecordEscapes:a.some(e=>!o.has(e)),...r?{parseFailure:r}:{}}}function pa(e){let t=[],n=w(e.hooks);if(n.length===0)return t;let r=null,i=null;return n.forEach((n,a)=>{let o=n.body;if(!ca(o)||o.language!==`js`)return;let s=o.source;if(typeof s!=`string`||s.trim()===``)return;let c=fa(s),l=typeof n.name==`string`&&n.name?n.name:`#${a}`;c.parseFailure&&t.push({severity:`warning`,rule:Qi,where:`hook "${l}" \u203A body`,path:`hooks[${a}].body.source`,message:`L2 body did not parse (${br(c.parseFailure)}), so its write set was read from a partially recovered tree \u2014 an undeclared field write in the unread part is not reported.`,hint:xr});let u=c.writes.filter(e=>ra.has(e.patternId));if(u.length===0)return;r??=la(e),i??=wt(e);let d=(Array.isArray(n.object)?n.object:[n.object]).filter(e=>typeof e==`string`&&e.trim()!==``),f=d.map(e=>ua(r,e)),p=d.length>0&&!d.includes(`*`)&&f.every(e=>e!==void 0),m=`hook "${l}" \u203A body`,h=`hooks[${a}].body.source`,g=new Set;for(let e of u){let n=`${e.object??``}\0${e.field}`;if(!g.has(n)){if(e.object===void 0){if(!p)continue;if(oa.has(e.field)){if(!d.every(t=>i.get(t)?.has(e.field)))continue;g.add(n);let r=d.length===1?d[0]:d.join(`, `);t.push({severity:`warning`,rule:$i,where:m,path:h,message:`body writes '${e.field}' to its input, and ${Tt(r,e.field)} \u2014 `+sa(),hint:Et(r,e.field)});continue}if(f.some(t=>t.has(e.field)))continue;g.add(n);let r=d.length===1?`object '${d[0]}'`:`none of its target objects (${d.join(`, `)})`,a=d.length===1?`declares no such field`:`declare that field`;t.push({severity:`warning`,rule:Zi,where:m,path:h,message:`body writes '${e.field}' to its input, but ${r} ${a}. The sandboxed script runs clean and the value is copied back onto the record payload unfiltered, so the write is then REFUSED at run time \u2014 INVALID_FIELD / 400, identically on every driver (#4271). The record is never written, and the refusal names the field far from the body that wrote it.`,hint:ha(e.field,ma(f))})}else{let a=ua(r,e.object);if(!a||a.has(e.field))continue;if(oa.has(e.field)){if(!i.get(e.object)?.has(e.field))continue;g.add(n),t.push({severity:`warning`,rule:$i,where:m,path:h,message:`body calls ctx.api.object('${e.object}').${e.method??`update`}(\u2026) writing '${e.field}', and ${Tt(e.object,e.field)} \u2014 ${sa()}`,hint:Et(e.object,e.field)});continue}g.add(n),t.push({severity:`warning`,rule:Zi,where:m,path:h,message:`body calls ctx.api.object('${e.object}').${e.method??`update`}(\u2026) writing '${e.field}', but object '${e.object}' declares no such field. ctx.api is a scoped handle on the running engine, so the payload arrives as an ordinary CALLER write and the declared-field door REFUSES it at run time \u2014 INVALID_FIELD / 400, identically on every driver (#4271), before any statement is built. The nested write lands nothing, and the refusal escapes the body and fails the operation that triggered the hook.`,hint:ha(e.field,[...a])})}}}}),t}function ma(e){let t=new Set;for(let n of e)for(let e of n??[])t.add(e);return[...t]}function ha(e,t){let n=x(g(e,[...t,...oa]));return(n?`${n} `:``)+`Fix the field name, or declare '${e}' on the object. Only the literal write patterns in HOOK_BODY_WRITE_PATTERNS are checked \u2014 computed keys, spreads and aliased input are not \u2014 and this warning never blocks a build.`}var ga=`hook-api-update-readonly-field`,_a=`hook-api-update-readonly-when-field`,va=[`api-crud-literal`],ya=[{id:`input-property-assign`,reason:"a `ctx.input.<field> = ...` stamp is a SERVER value, not a caller-supplied one - stripReadonlyFields drops a key only while it is still Object.is-equal to what the caller supplied, so the stamp survives. readonly + a before-hook stamp is the CORRECT pairing this rule must never flag"},{id:`input-object-assign`,reason:`Object.assign(ctx.input, { ... }) reaches the same in-flight payload as the property form and survives the strip for the same reason - the channel is what decides, not the syntax`},{id:`record-property-assign`,reason:`a hook sandbox context has no ctx.record at all, so the expression throws at run time rather than silently no-op-ing - a loud failure on the first run is not this rule’s business (the action surface owns that shape)`}],ba=new Set(va),xa=new Set([`update`,`updateById`,`insert`]),Sa=new Set([`update`,`updateById`]),Ca=new Set([`update`]),wa=`id`;function Ta(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function Ea(e){let t=[],n=w(e.hooks);if(n.length===0)return t;let r=null,i=null;return n.forEach((n,a)=>{let o=n.body;if(!Ta(o)||o.language!==`js`)return;let s=o.source;if(typeof s!=`string`||s.trim()===``||n.runAs===`system`)return;let c=fa(s);if(c.parseFailure)return;let l=c.writes.filter(e=>ba.has(e.patternId)&&typeof e.object==`string`&&e.method!==void 0&&xa.has(e.method));if(l.length===0)return;r??=Gi(w(e.objects)),i??=Ki(w(e.objects));let u=`hook "${typeof n.name==`string`&&n.name?n.name:`#${a}`}" > body`,d=`hooks[${a}].body.source`,f=new Set;for(let e of l){let n=e.object,a=e.method;if(e.field===wa&&Ca.has(a))continue;let o=r.get(n);if(!o||o.size===0)continue;let s=o.get(e.field);if(!s)continue;let c=`${n} ${e.field}`;if(f.has(c))continue;let l=`ctx.api.object('${n}').${a}(...)`,p=!Sa.has(a);p&&i.has(n)||(s.readonly?(f.add(c),t.push({severity:`error`,rule:ga,where:u,path:d,message:p?`body writes field '${e.field}' through ${l}, and object '${n}' declares it readonly:true. A hook's ctx.api is a ScopedContext over the TRIGGERING operation's context, so on every non-system trigger the engine strips readonly keys from that INSERT payload exactly as it does from an UPDATE - the row is created WITHOUT this column (it falls back to the field's defaultValue), while the call still returns success.`:`body writes field '${e.field}' through ${l}, and object '${n}' declares it readonly:true. A hook's ctx.api is a ScopedContext over the TRIGGERING operation's context, so on every non-system trigger the engine strips readonly keys from that UPDATE payload - the write never lands, while the call still returns success.`,hint:p?`Seeding a readonly column at create time is a SYSTEM act. To keep writing it from here, declare runAs: 'system' on this hook: the strip skips a system context, so the write lands, and the triggering user is still stamped on the record. Or stamp it on '${n}''s OWN beforeInsert hook - ctx.input.${e.field} = ... is a server value and survives the strip. Note that ctx.api.sudo() is NOT an option from a body: sudo() lives on the in-process ScopedContext and is not marshalled into the sandbox, so calling it here is a TypeError at run time. Otherwise drop '${e.field}' from this payload, or drop readonly:true from the field.`:`If automation is meant to maintain '${e.field}', stamp it on the record's OWN hook - ctx.input.${e.field} = ... in beforeInsert/beforeUpdate survives the strip, and is the recommended shape. To keep writing it CROSS-OBJECT from here, declare runAs: 'system' on this hook: the strip skips a system context, so the write lands, and the triggering user is still stamped on the record. Note that ctx.api.sudo() is NOT an option from a body: sudo() lives on the in-process ScopedContext and is not marshalled into the sandbox, so calling it here is a TypeError at run time. Otherwise drop readonly:true from '${e.field}'.`})):s.readonlyWhen&&!p&&(f.add(c),t.push({severity:`warning`,rule:_a,where:u,path:d,message:`body writes field '${e.field}' through ${l}, and object '${n}' declares it readonlyWhen. On records whose predicate is TRUE that UPDATE strips the field, so this write may silently not land depending on the record's state.`,hint:`Either confirm this call only targets records whose readonlyWhen predicate is FALSE, or derive '${e.field}' in a beforeUpdate hook on '${n}' - a hook-derived value is not caller-supplied and does land, even on a locked record. Elevation is not a workaround here: a system context does not waive the conditional lock (unlike the static readonly strip), so neither runAs: 'system' nor ctx.api.sudo() helps - and sudo() is not marshalled into the sandbox in any case (calling it from a body is a TypeError at run time). Otherwise drop '${e.field}' from this payload. This warning never blocks a build.`})))}}),t}var Da=`action-body-write-unknown-field`,Oa=`action-record-write-discarded`,ka=`action-body-source-unparseable`,Aa=`action-body-write-unprovisioned-anchor`,ja=[`api-crud-literal`],Ma=[`record-property-assign`],Na=[{id:`input-property-assign`,reason:"an action's ctx.input is its params bag (`input: unwrapProxyToPlain(actionCtx?.params)`), not a record — `ctx.input.<name>` writes a declared PARAMETER, which object fields cannot judge"},{id:`input-object-assign`,reason:`same surface as input-property-assign — Object.assign(ctx.input, …) targets the params bag`}],Pa=ea.filter(e=>ja.includes(e.id)),Fa=ea.filter(e=>Ma.includes(e.id)),Ia=new Set(ja),La=new Set(Ma),Ra=e=>!!e&&typeof e==`object`&&!Array.isArray(e);function za(e,t){return typeof e.object==`string`&&e.object?e.object:typeof e.objectName==`string`&&e.objectName?e.objectName:t}function Ba(e){let t=[],n=new Set,r=(e,r,i)=>{w(e).forEach((e,a)=>{if((typeof e.type==`string`?e.type:`script`)!==`script`)return;let o=e.body;if(!Ra(o)||o.language!==`js`)return;let s=o.source;if(typeof s!=`string`||s.trim()===``)return;let c=typeof e.name==`string`&&e.name?e.name:`#${a}`,l=`${za(e,i)??``}\0${c}\0${s}`;n.has(l)||(n.add(l),t.push({name:c,source:s,path:`${r}[${a}].body.source`}))})};return r(e.actions,`actions`),w(e.objects).forEach((e,t)=>{let n=typeof e.name==`string`&&e.name?e.name:void 0;r(e.actions,`objects[${t}].actions`,n)}),t}function Va(e){let t=[];if(!Ra(e))return t;let n=Ba(e);if(n.length===0)return t;let r=null,i=null;for(let a of n){if(!/\bapi\b/.test(a.source)&&!/\brecord\b/.test(a.source))continue;let{writes:n,ctxRecordEscapes:o,parseFailure:s}=fa(a.source),c=n.filter(e=>Ia.has(e.patternId)),l=n.filter(e=>La.has(e.patternId)),u=`action "${a.name}" \u203A body`;if(s&&t.push({severity:`warning`,rule:ka,where:u,path:a.path,message:`L2 body did not parse (${br(s)}), so its write set was read from a partially recovered tree \u2014 an undeclared field write in the unread part is not reported.`,hint:xr}),c.length===0&&l.length===0)continue;if(l.length>0&&!o){let e=new Set;for(let n of l)e.has(n.field)||(e.add(n.field),t.push({severity:`warning`,rule:Oa,where:u,path:a.path,message:`body assigns ctx.record.${n.field}, but an action's ctx.record is a plain snapshot the runtime never writes back \u2014 the action returns success and the assignment is discarded, whether or not '${n.field}' is a declared field (#4345).`,hint:`To persist it, write through the API: ctx.api.object('<object>').updateById(ctx.recordId, { ${n.field}: \u2026 }). Reported only because ctx.record is never passed anywhere in this body \u2014 mutating the snapshot and then handing it to an API write is a live payload and is not flagged. This warning never blocks a build.`}))}if(c.length===0)continue;r??=la(e),i??=wt(e);let d=new Set;for(let e of c){if(e.object===void 0)continue;let n=`${e.object}\0${e.field}`;if(d.has(n))continue;let o=ua(r,e.object);if(o&&!o.has(e.field)){if(oa.has(e.field)){if(!i.get(e.object)?.has(e.field))continue;d.add(n),t.push({severity:`warning`,rule:Aa,where:u,path:a.path,message:`body calls ctx.api.object('${e.object}').${e.method??`update`}(\u2026) writing '${e.field}', and ${Tt(e.object,e.field)} \u2014 ${sa()}`,hint:Et(e.object,e.field)});continue}d.add(n),t.push({severity:`warning`,rule:Da,where:u,path:a.path,message:`body calls ctx.api.object('${e.object}').${e.method??`update`}(\u2026) writing '${e.field}', but object '${e.object}' declares no such field. ctx.api is a scoped handle on the running engine, so the payload arrives as an ordinary CALLER write and the declared-field door REFUSES it at run time \u2014 INVALID_FIELD / 400, identically on every driver (#4271), before any statement is built. The write lands nothing, and the refusal escapes the body and fails the action.`,hint:Ha(e.field,[...o])})}}}return t}function Ha(e,t){let n=x(g(e,[...t,...oa]));return(n?`${n} `:``)+`Fix the field name, or declare '${e}' on the object. Only the literal write patterns in ACTION_BODY_WRITE_PATTERNS are checked \u2014 an action's ctx.input is its params bag, so it is not a record-write surface and is never resolved against fields \u2014 and this warning never blocks a build.`}var Ua=`action-api-update-readonly-when-field`,Wa=[`api-crud-literal`],Ga=[{id:`record-property-assign`,reason:"an action's ctx.record is a DEAD SNAPSHOT - `buildActionSandboxContext` binds `record: unwrapProxyToPlain(actionCtx?.record)` and `boundActionHandler` returns `result.value` with no write-back (`applyMutationsToInput` is the hook path’s alone), so the assignment never reaches the engine and no readonly strip is ever consulted. A readonly verdict on a write that reaches no write path at all would be a false positive on every occurrence. The shape is not left unreported: `action-record-write-discarded` owns it, and states the true reason (the write is discarded for DECLARED and undeclared fields alike)"},{id:`input-property-assign`,reason:"an action's ctx.input is its PARAMS BAG (`input: unwrapProxyToPlain(actionCtx?.params)`), not a record payload - the names it writes are declared parameters, which object field metadata cannot judge"},{id:`input-object-assign`,reason:`same surface as input-property-assign - Object.assign(ctx.input, ...) targets the params bag`}],Ka=new Set(Wa),qa=new Set([`update`,`updateById`]),Ja=new Set([`update`]),Ya=`id`,Xa=e=>!!e&&typeof e==`object`&&!Array.isArray(e);function Za(e){let t=[];if(!Xa(e))return t;let n=Ba(e);if(n.length===0)return t;let r=null;for(let i of n){if(!/\bapi\b/.test(i.source))continue;let n=fa(i.source);if(n.parseFailure)continue;let a=n.writes.filter(e=>Ka.has(e.patternId)&&typeof e.object==`string`&&e.method!==void 0&&qa.has(e.method));if(a.length===0)continue;r??=Gi(w(e.objects));let o=`action "${i.name}" > body`,s=new Set;for(let e of a){let n=e.object,a=e.method;if(e.field===Ya&&Ja.has(a))continue;let c=r.get(n);if(!c||c.size===0)continue;let l=c.get(e.field);if(!l||!l.readonlyWhen)continue;let u=`${n} ${e.field}`;if(s.has(u))continue;s.add(u);let d=`ctx.api.object('${n}').${a}(...)`;t.push({severity:`warning`,rule:Ua,where:o,path:i.path,message:`body writes field '${e.field}' through ${d}, and object '${n}' declares it readonlyWhen. An action body runs elevated, which exempts it from the STATIC readonly strip but NOT from the conditional one - on records whose predicate is TRUE that UPDATE still drops the field, so this write may silently not land depending on the record's state.`,hint:`Elevation is not a workaround here: an action body is already system-elevated and the readonlyWhen lock still applies, so ctx.api.sudo() changes nothing. Either confirm this call only targets records whose readonlyWhen predicate is FALSE, or derive '${e.field}' in a beforeUpdate hook on '${n}' (a hook-written value is not caller-supplied and does land, even on a locked record). Otherwise drop '${e.field}' from this payload. This warning never blocks a build.`})}}return t}var Qa=`view-container-shape`,$a=[`list`,`form`,`listViews`,`formViews`];function eo(e){return Array.isArray(e)?e.map((e,t)=>({key:`[${t}]`,value:e})):e&&typeof e==`object`?Object.entries(e).map(([e,t])=>({key:`.${e}`,value:t})):[]}function to(e){let t=e=>e&&typeof e==`object`&&!Array.isArray(e)?Object.keys(e).length:0;return+!!e.list+ +!!e.form+t(e.listViews)+t(e.formViews)}function no(e){let t=[];if(!e||typeof e!=`object`)return t;let n=e.viewItems;n!=null&&eo(n).length>0&&t.push({severity:`error`,rule:Qa,where:`viewItems`,path:`viewItems`,message:"`viewItems` is the machine-assembled channel for non-container view artifacts in runtime-assembled manifests (package export, environment artifacts) — it is not an authoring surface.",hint:"Author views as defineView containers in `views:`; author a standalone view through the metadata door (Studio / `PUT /api/v1/meta/view`), not in stack source."});for(let{key:n,value:r}of eo(e.views)){if(!r||typeof r!=`object`||Array.isArray(r))continue;let e=r;if(e.viewKind!=null){let r=typeof e.name==`string`?` ("${e.name}")`:``;t.push({severity:`error`,rule:Qa,where:`views${n}${r}`,path:`views${n}`,message:"A ViewItem record is not a view container: the stack `views:` collection carries containers only — `viewKind` belongs to a single VIEW, not to the container. The registration loop refuses this entry (#5320).",hint:"Wrap it in a defineView container: defineView({ list: { type, data, columns, ... }, listViews: { ... } }) — or author the standalone view through the metadata door (Studio / `PUT /api/v1/meta/view`). Machine-assembled manifests carry it under `viewItems:`."});continue}if(to(e)>0)continue;let i=typeof e.name==`string`?` ("${e.name}")`:``,a=!$a.some(t=>t in e)&&[`type`,`columns`,`data`,`filter`,`sort`].some(t=>t in e);t.push({severity:`error`,rule:Qa,where:`views${n}${i}`,path:`views${n}`,message:a?"Flat list-view object is not a view container: `ViewSchema` strips its keys, so it parses to an EMPTY container — zero views register and the Console renders no view for it.":"View container defines no views — all of `list` / `form` / `listViews` / `formViews` are absent or empty, so nothing registers.",hint:`Wrap every view in a defineView container: defineView({ list: { type, data, columns, ... }, listViews: { ... }, formViews: { ... } }). See examples/app-showcase/src/ui/views/task.view.ts.`})}return t}var ro=`style-node-missing-id`,io=`style-classname-tailwind`,ao=`style-responsive-no-base`,oo=`style-unknown-css-property`,so=`style-unknown-token`,co=[`large`,`medium`,`small`,`xsmall`],lo=new Set(`space-1.space-2.space-3.space-4.space-5.space-6.space-8.space-10.space-12.radius.radius-sm.radius-md.radius-lg.radius-xl.shadow-sm.shadow-md.shadow-lg.surface.surface-sunken.text-strong.text-muted.brand.brand-foreground.hairline.background.foreground.card.card-foreground.popover.popover-foreground.primary.primary-foreground.secondary.secondary-foreground.muted.muted-foreground.accent.accent-foreground.destructive.destructive-foreground.border.input.ring.success.success-foreground.warning.warning-foreground.chart-1.chart-2.chart-3.chart-4.chart-5`.split(`.`)),uo=new Set(`display.position.top.right.bottom.left.inset.zIndex.overflow.overflowX.overflowY.visibility.boxSizing.float.clear.width.height.minWidth.minHeight.maxWidth.maxHeight.aspectRatio.margin.marginTop.marginRight.marginBottom.marginLeft.marginInline.marginBlock.padding.paddingTop.paddingRight.paddingBottom.paddingLeft.paddingInline.paddingBlock.flex.flexDirection.flexWrap.flexGrow.flexShrink.flexBasis.alignItems.alignContent.alignSelf.justifyContent.justifyItems.justifySelf.gap.rowGap.columnGap.order.placeItems.placeContent.grid.gridTemplate.gridTemplateColumns.gridTemplateRows.gridTemplateAreas.gridColumn.gridRow.gridArea.gridAutoFlow.gridAutoColumns.gridAutoRows.color.backgroundColor.background.backgroundImage.backgroundSize.backgroundPosition.backgroundRepeat.backgroundClip.opacity.mixBlendMode.fontSize.fontWeight.fontFamily.fontStyle.lineHeight.letterSpacing.textAlign.textTransform.textDecoration.textOverflow.whiteSpace.wordBreak.overflowWrap.fontVariantNumeric.verticalAlign.textShadow.border.borderTop.borderRight.borderBottom.borderLeft.borderColor.borderWidth.borderStyle.borderRadius.borderTopLeftRadius.borderTopRightRadius.borderBottomLeftRadius.borderBottomRightRadius.outline.outlineOffset.boxShadow.transform.transformOrigin.transition.transitionProperty.transitionDuration.transitionTimingFunction.transitionDelay.animation.filter.backdropFilter.willChange.cursor.pointerEvents.userSelect.objectFit.objectPosition.content`.split(`.`)),fo=/var\(\s*--([a-zA-Z0-9-]+)\s*[,)]/g,po=/^(sm|md|lg|xl|2xl|hover|focus|active|disabled|dark|group-hover|peer-[a-z]+|first|last|odd|even):/,mo=/^-?(p|m|px|py|pt|pb|pl|pr|mx|my|mt|mb|ml|mr|gap|gap-x|gap-y|space-x|space-y|w|h|min-w|max-w|min-h|max-h|size|text|leading|tracking|bg|border|rounded|shadow|ring|opacity|inset|top|bottom|left|right|z|order|col|row|grid-cols|grid-rows|basis)-(\d+(\.\d+)?|\d+\/\d+|px|full|auto|none|screen|min|max|fit|xs|sm|md|lg|xl|2xl|3xl|4xl|5xl|6xl)$/,ho=/^(flex|grid|block|inline|inline-block|inline-flex|hidden|contents|table|flow-root|grow|shrink|truncate|italic|underline|uppercase|lowercase|capitalize|antialiased|absolute|relative|fixed|sticky|static|isolate|flex-col|flex-row|flex-wrap|flex-nowrap|items-center|items-start|items-end|items-stretch|justify-center|justify-between|justify-around|justify-start|justify-end|text-center|text-left|text-right|font-bold|font-semibold|font-medium|font-normal|tabular-nums)$/;function go(e){return e.split(/\s+/).some(e=>e?!!(po.test(e)||/\[[^\]]+\]/.test(e)||mo.test(e)||ho.test(e)):!1)}function _o(e){let t=e.properties??{},n=[];for(let r of[e.children,t.children,e.body,t.body])Array.isArray(r)&&n.push(...r.filter(e=>e&&typeof e==`object`));return n}function vo(e,t,n,r){let i=typeof e.id==`string`?e.id:void 0,a=typeof e.type==`string`?e.type:`node`,o=`page "${t}" \u203A ${i?`node "${i}"`:`<${a}>`}`,s=e.responsiveStyles,c=!!s&&typeof s==`object`&&co.some(e=>s[e]);if(c&&!i&&r.push({severity:`error`,rule:ro,where:o,path:n,message:"Node has responsiveStyles but no `id`; scoped CSS cannot be generated and the styles are silently dropped.",hint:"Add a stable `id` to this node."}),c&&!s.large&&co.slice(1).some(e=>s[e])&&r.push({severity:`warning`,rule:ao,where:o,path:n,message:"responsiveStyles sets a smaller breakpoint but no `large` base; the node is unstyled at desktop width.",hint:"Put the unconditional/base styles under `responsiveStyles.large` (desktop-first)."}),typeof e.className==`string`&&e.className.trim()&&go(e.className)&&r.push({severity:`warning`,rule:io,where:o,path:n,message:`\`className\` contains Tailwind-looking utilities ("${e.className.trim().slice(0,60)}"); these are not compiled from metadata and will silently do nothing.`,hint:"Style this node with `responsiveStyles` + design tokens instead of `className` (ADR-0065)."}),s&&typeof s==`object`)for(let e of co){let t=s[e];if(t&&typeof t==`object`){for(let[i,a]of Object.entries(t))if(!i.startsWith(`--`)&&!uo.has(i)&&r.push({severity:`warning`,rule:oo,where:o,path:`${n}.responsiveStyles.${e}`,message:`Unknown CSS property "${i}" (typo?); if unintended it will not apply.`,hint:"Use a camelCase CSS property name (e.g. `flexDirection`, `backgroundColor`)."}),typeof a==`string`){let t;for(fo.lastIndex=0;t=fo.exec(a);){let a=t[1];!lo.has(a)&&!a.startsWith(`tw-`)&&r.push({severity:`warning`,rule:so,where:o,path:`${n}.responsiveStyles.${e}.${i}`,message:`References unknown design token \`var(--${a})\` (typo?); it will not resolve.`,hint:"Use a token from the ADR-0065 palette (e.g. `var(--space-6)`, `var(--surface)`, `hsl(var(--primary))`)."})}}}}let l=_o(e);for(let e=0;e<l.length;e++)vo(l[e],t,`${n}.children[${e}]`,r)}function yo(e){let t=[],n=w(e.pages);for(let e=0;e<n.length;e++){let r=n[e],i=typeof r.name==`string`?r.name:`pages[${e}]`,a=w(r.regions);for(let n=0;n<a.length;n++){let r=w(a[n].components);for(let a=0;a<r.length;a++)vo(r[a],i,`pages[${e}].regions[${n}].components[${a}]`,t)}}return t}function bo(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function D(e,t){if(Array.isArray(e)){let n=[];for(let r=0;r<e.length;r++)bo(e[r])&&n.push({rec:e[r],path:`${t}[${r}]`});return n}return bo(e)?Object.entries(e).filter(([,e])=>bo(e)).map(([e,n])=>({rec:{name:e,...n},path:`${t}.${e}`})):[]}function xo(e,t={}){let n=[];for(let{rec:r,path:i}of D(e.pages,`pages`)){if(!r||r.kind!==`html`&&r.kind!==`jsx`)continue;let e=String(r.name??i),a=r.source;if(typeof a!=`string`||a.trim()===``){n.push({severity:`error`,rule:`jsx-page-empty-source`,where:`page "${e}"`,path:`${i}.source`,message:`kind:'${r.kind}' page has no \`source\`.`,hint:"Author the page as a constrained JSX/Tailwind string in `source`."});continue}let{diagnostics:o}=t.manifest?tt(a,t.manifest):Le(a);for(let t of o)n.push({severity:t.severity,rule:`jsx-${t.code}`,where:t.tag?`page "${e}" \u203A <${t.tag}>`:`page "${e}"`,path:`${i}.source`,message:t.message,hint:`The source is parsed (never executed) and compiled to the SDUI tree at save time — fix the JSX.`})}return n}var So=null;function Co(){if(So)return So;let e=import.meta.url?import.meta.url:typeof __filename<`u`?__filename:process.cwd()+`/`;try{So=(0,C.createRequire)(e)(`sucrase`).transform}catch(e){throw Error(`@objectstack/lint: validating a kind:'react' page requires the "sucrase" package, which could not be loaded (${e instanceof Error?e.message:String(e)}). It is a declared dependency of @objectstack/lint \u2014 if this deployment prunes packages, keep "sucrase" in the image; it is only loaded when a react-source page is validated.`)}return So}function wo(e){let t=[];for(let{rec:n,path:r}of D(e.pages,`pages`)){if(!n||n.kind!==`react`)continue;let e=String(n.name??r),i=n.source;if(typeof i!=`string`||i.trim()===``){t.push({severity:`error`,rule:`react-page-empty-source`,where:`page "${e}"`,path:`${r}.source`,message:"kind:'react' page has no `source`.",hint:"Author the page as a real React component string in `source`."});continue}let a=Co();try{a(i,{transforms:[`jsx`,`typescript`],production:!0})}catch(n){let i=n instanceof Error?n.message:String(n);t.push({severity:`error`,rule:`react-page-syntax`,where:`page "${e}"`,path:`${r}.source`,message:`kind:'react' source has a syntax error: ${i.split(`
|
|
4
|
-
`)[0]}`,hint:`The source is transpiled (never executed) at build to catch syntax errors early — fix the JS/JSX.`})}}return t}var To=`searchable-field-unknown`,Eo=`searchable-field-unsearchable`,Do=`searchable-field-unprovisioned`;function O(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function k(e){return typeof e==`string`&&e.length>0?e:void 0}function Oo(e){let t=e.fields;if(!t||typeof t!=`object`)return null;let n=new Set,r={};for(let e of w(t)){let t=k(e.name);t&&(n.add(t),r[t]={type:typeof e.type==`string`?e.type:void 0,hidden:e.hidden===!0})}return n.size===0?null:{names:n,fields:r,searchableFields:Array.isArray(e.searchableFields)?e.searchableFields.filter(e=>typeof e==`string`):void 0,displayField:k(e.nameField)??k(e.displayNameField)}}function ko(e){let t=e.fields,n=(e.searchableFields??[]).filter(t=>!e.names.has(t)&&bt.has(t));if(n.length>0){t={...t};for(let e of n)t[e]={}}let{allowed:r,source:i}=pe({fields:t,searchableFields:e.searchableFields,displayField:e.displayField});return{allowed:new Set(r),source:i,declaredList:r}}function Ao(e){let t=new Map;if(!O(e))return t;for(let n of w(e.objects)){let e=k(n.name);e&&t.set(e,Oo(n))}return t}function jo(e,t,n,r,i,a,o=`narrowing`,s){let c=[];if(!Array.isArray(e)||e.length===0||!t||!n.has(t))return c;let l=n.get(t);if(!l)return c;let u=l.names,d=s?.get(t),f=o===`narrowing`?ko(l):void 0;for(let n=0;n<e.length;n++){let s=e[n],p=k(s);if(!p)continue;if(!u.has(p)&&!bt.has(p)){let e=p.includes(`.`);c.push({severity:`error`,rule:To,where:r,path:`${i}[${n}]`,message:`${a} entry "${p}" is not a field on object "${t}". The declaration is stale: searching it can never match, and the engine silently drops it \u2014 leaving a narrower search than declared, or the auto-default set once every entry is dropped.`+(e?``:T(p,u)),hint:(e?`'search' scans this object's own columns, so a related record's column cannot be a search target — expand the relation and search the related object, or copy the value onto a stored text field here. `:`Fix the name, or add "${p}" to ${t}.fields. `)+`Clients echo this declaration verbatim as the '$searchFields' override, so a stale entry becomes a 400 INVALID_FIELD on list search (#4254), not just a quietly narrowed one.`+(u.size>0?` Object fields: ${[...u].sort().join(`, `)}.`:``)});continue}if(d?.has(p)&&c.push({severity:`warning`,rule:Do,where:r,path:`${i}[${n}]`,message:`${a} entry "${p}" resolves on object "${t}", but ${Tt(t,p)}`+(o===`narrowing`?` — clients echo this declaration verbatim as the '$searchFields' override, so every toolbar search on this list scans a column that is empty on every record: it reads as search coverage and matches nothing.`:` — 'search' scans it on every record and it can never match, so the object's searchable set is narrower than it declares. Should it be the ONLY entry that resolves, the set scans nothing at all.`),hint:Et(t,p)}),Xe(l.fields[p])){let e=l.fields[p]?.type;c.push({severity:`error`,rule:Eo,where:r,path:`${i}[${n}]`,message:`${a} entry "${p}" on object "${t}" is a virtual '${e}' field: its value is computed on read and never stored, so no driver materializes a column for 'search' to scan and the entry can never match. It reads as search coverage and delivers none \u2014 the runtime used to admit it verbatim because the declaration named it (#6674).`,hint:`Mirror the computed value onto a stored text field on "${t}" and declare that instead, or drop "${p}". At runtime the ingress gate now refuses this entry with 400 INVALID_FIELD, the same answer a stale entry gets (#4254).`});continue}if(!f||f.allowed.has(p)||!u.has(p))continue;let m=l.fields[p];if(f.source===`declared`){c.push({severity:`error`,rule:Eo,where:r,path:`${i}[${n}]`,message:`${a} entry "${p}" is outside object "${t}"'s declared searchableFields (${f.declaredList.join(`, `)}) \u2014 the set 'search' scans. Clients echo this declaration verbatim as the '$searchFields' override, and the runtime refuses an entry outside the allowed set: every toolbar search on this list returns 400 INVALID_FIELD (#4254).`,hint:`Add "${p}" to ${t}.searchableFields, or drop it from this view \u2014 a view narrows the object's searchable set, never widens it (ADR-0061).`});continue}let h=m?.type===`lookup`||m?.type===`master_detail`,g;if(vt.has(p))g=`a system/audit column, which the auto-default set never includes`;else if(m?.hidden)g=`hidden`;else if(typeof m?.type==`string`)g=`of type '${m.type}', which 'search' cannot scan`;else continue;c.push({severity:`error`,rule:Eo,where:r,path:`${i}[${n}]`,message:`${a} entry "${p}" on object "${t}" is ${g}. With no 'searchableFields' declared on the object, 'search' scans its text-like columns (${[...de,...te].join(` / `)}). Clients echo this declaration verbatim as the '$searchFields' override, and the runtime refuses it: every toolbar search on this list returns 400 INVALID_FIELD (#4254).`,hint:(h?`A ${m?.type} column stores only the referenced record's id, so it cannot be a keyword target \u2014 drop "${p}" from this view and, to search by the related record's title, mirror it onto a stored text field here and declare that instead. `:`Drop "${p}" from this view, or target a text-like field instead. `)+`Declaring 'searchableFields' on object "${t}" chooses the searchable set explicitly.`})}return c}function Mo(e){let t=[];if(!O(e))return t;let n=w(e.objects),r=Ao(e),i=wt(e),a=(e,n,a,o,s,c)=>{t.push(...jo(e,n,r,a,o,s,c,i))};for(let e=0;e<n.length;e++){let t=n[e];if(!O(t))continue;let r=k(t.name),i=r?`object "${r}"`:`objects[${e}]`;if(a(t.searchableFields,r,i,`objects[${e}].searchableFields`,`searchableFields`,`canonical`),O(t.listViews))for(let[n,o]of Object.entries(t.listViews))O(o)&&a(o.searchableFields,No(o)??r,`${i} \u203A listViews.${n}`,`objects[${e}].listViews.${n}.searchableFields`,`list-view searchableFields`,`narrowing`)}let o=w(e.views);for(let e=0;e<o.length;e++){let t=o[e];if(!O(t))continue;let n=k(t.name)??k(t.objectName)??`#${e}`,r=k(t.objectName)??k(t.object);if(t.viewKind===`list`&&!O(t.config)&&a(t.searchableFields,No(t)??r,`view "${n}" (flattened list overlay)`,`views[${e}].searchableFields`,`list-view searchableFields`,`narrowing`),t.viewKind===`list`&&O(t.config)&&a(t.config.searchableFields,No(t.config)??r,`view "${n}" (ViewItem record)`,`views[${e}].config.searchableFields`,`list-view searchableFields`,`narrowing`),O(t.list)&&a(t.list.searchableFields,No(t.list)??r,`view "${n}" \u203A list`,`views[${e}].list.searchableFields`,`list-view searchableFields`,`narrowing`),O(t.listViews))for(let[i,o]of Object.entries(t.listViews))O(o)&&a(o.searchableFields,No(o)??r,`view "${n}" \u203A listViews.${i}`,`views[${e}].listViews.${i}.searchableFields`,`list-view searchableFields`,`narrowing`)}return t}function No(e){let t=e.data;return O(t)?k(t.object):void 0}function Po(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function Fo(e){return typeof e==`string`&&e.length>0?e:void 0}var Io=new Set([`html`,`react`,`jsx`]);function Lo(e){let t=Fo(e.kind);return t!==void 0&&Io.has(t)}function Ro(e,t){let n=[];if(!Po(e)||Lo(e))return n;let r=Fo(e.object),i=new Set,a=(e,t,r)=>{if(!Po(e)||i.has(e))return;let o=Po(e.properties)?e.properties:void 0,s=Fo((Po(e.dataSource)?e.dataSource:void 0)?.object)??Fo(o?.object)??r;if(n.push({component:e,path:t,objectName:s}),o){i.add(e);try{if(Array.isArray(o.items))for(let e=0;e<o.items.length;e++){let n=o.items[e];if(Po(n)&&Array.isArray(n.children))for(let r=0;r<n.children.length;r++)a(n.children[r],`${t}.properties.items[${e}].children[${r}]`,s)}if(Array.isArray(o.children))for(let e=0;e<o.children.length;e++)a(o.children[e],`${t}.properties.children[${e}]`,s);for(let e of[`body`,`footer`]){let n=o[e];if(Array.isArray(n))for(let r=0;r<n.length;r++)a(n[r],`${t}.properties.${e}[${r}]`,s)}}finally{i.delete(e)}}},o=Array.isArray(e.regions)?e.regions:[];for(let e=0;e<o.length;e++){let n=o[e];if(Po(n)&&Array.isArray(n.components))for(let i=0;i<n.components.length;i++)a(n.components[i],`${t}.regions[${e}].components[${i}]`,r)}let s=Po(e.slots)?e.slots:void 0;if(s)for(let[e,n]of Object.entries(s)){let i=Array.isArray(n)?n:[n],o=Array.isArray(n);for(let n=0;n<i.length;n++)a(i[n],`${t}.slots.${e}${o?`[${n}]`:``}`,r)}return n}function zo(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function Bo(e){return typeof e==`string`&&e.length>0?e:void 0}function Vo(e){let t=new Map;if(!zo(e))return t;for(let n of w(e.objects)){let e=Bo(n.name);if(!e)continue;let r=new Set;for(let e of w(n.fieldGroups)){let t=Bo(e.key)??Bo(e.name);t&&r.add(t)}t.set(e,r)}return t}function Ho(e,t,n=`.`){if(!Array.isArray(e))return[];let r=[];for(let i=0;i<e.length;i++){let a=e[i];if(!zo(a))continue;let o=Bo(a.group);o&&r.push({key:o,path:`${t}[${i}]${n}group`})}return r}function Uo(e,t,n,r,i){let a=[];if(!t)return a;let o=n.get(t);if(!o)return a;for(let n of e)o.has(n.key)||a.push({severity:`warning`,rule:i,where:r,path:n.path,message:`section references field group "${n.key}", which object "${t}" does not declare \u2014 the section inherits its members from that group, so it resolves to no fields and the whole section silently does not render`,hint:`Fix the key, or declare it: \`fieldGroups: [{ key: '${n.key}', label: '\u2026' }]\` on ${t}, with each member field carrying \`group: '${n.key}'\`. `+(o.size>0?`Declared groups on ${t}: ${[...o].sort().join(`, `)}.`:`${t} declares no field groups at all, so no section on it can reference one yet \u2014 enumerate the members with \`fields\` until it does.`)});return a}var Wo=`page-field-unknown`,Go=`page-field-unprovisioned`,Ko=`page-section-group-unknown`;function A(e){return typeof e==`string`&&e.length>0?e:void 0}function qo(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function j(e,t){let n=[],r=(e,t)=>{let r=A(e);if(r){n.push({name:r,path:t});return}if(!qo(e))return;let i=A(e.field)??A(e.name);i&&n.push({name:i,path:`${t}.${A(e.field)?`field`:`name`}`})};if(Array.isArray(e))for(let n=0;n<e.length;n++)r(e[n],`${t}[${n}]`);else r(e,t);return n}function Jo(e,t){if(typeof e==`string`){let n=e.trim().split(/\s+/)[0];return n?[{name:n,path:t}]:[]}return j(e,t)}var Yo={"record:highlights":{props:[`fields`]},"record:details":{props:[`fields`,`hideFields`],nestedSections:[`sections`]},"record:path":{props:[`statusField`]},"element:number":{props:[`field`]},"element:record_picker":{props:[`labelField`]}},Xo=`record:related_list`;function Zo(e,t,n,r=`.`){let i=Yo[e];if(!i)return null;let a=[];for(let e of i.props??[])a.push(...j(t[e],`${n}${r}${e}`));for(let e of i.nestedSections??[]){let i=Array.isArray(t[e])?t[e]:[];for(let t=0;t<i.length;t++){let o=i[t];qo(o)&&a.push(...j(o.fields,`${n}${r}${e}[${t}].fields`))}}return a}function Qo(e,t,n,r=`.`){let i=Yo[e];if(!i)return null;let a=[];for(let e of i.nestedSections??[])a.push(...Ho(t[e],`${n}${r}${e}`,r));return a}function $o(e,t,n=`.`){let r=qo(e.add)?e.add:void 0,i=r&&qo(r.picker)?r.picker:void 0,a=e=>`${t}${n}${e}`;return{relatedObject:A(e.objectName),related:[...j(e.columns,a(`columns`)),...Jo(e.sort,a(`sort`)),...j(e.filter,a(`filter`)),...j(e.relationshipField,a(`relationshipField`)),...r?j(r.linkField,a(`add.linkField`)):[]],parent:j(e.relationshipValueField,a(`relationshipValueField`)),pickerObject:i?A(i.object):void 0,picker:i?[...j(i.valueField,a(`add.picker.valueField`)),...j(i.labelField,a(`add.picker.labelField`))]:[]}}function es(e){let t=new Map;if(!qo(e))return t;for(let n of w(e.objects)){let e=A(n.name);if(!e)continue;let r=new Set;for(let e of w(n.fields)){let t=A(e.name);t&&r.add(t)}t.set(e,r)}return t}function ts(e,t,n,r,i=`skipped`,a){let o=[];if(!t)return o;let s=n.get(t);if(!s)return o;let c=a?.get(t);for(let n of e)if(!n.name.includes(`.`)){if(s.has(n.name)||bt.has(n.name)){c?.has(n.name)&&o.push({severity:`warning`,rule:Go,where:r,path:n.path,message:`field "${n.name}" resolves on object "${t}", but ${Tt(t,n.name)}`+(i===`queried`?` — it is used in a QUERY, so the predicate can never match a real value: on SQLite it silently degrades to constant-false and the surface renders an empty result that looks exactly like "there is no data".`:` — the component renders it, blank, on every record.`),hint:Et(t,n.name)});continue}o.push({severity:i===`queried`?`error`:`warning`,rule:Wo,where:r,path:n.path,message:`field "${n.name}" is not a field on object "${t}" \u2014 `+(i===`queried`?`it is used in a QUERY, so the predicate can never match: the surface renders an empty result that looks exactly like "there is no data".`:`the component silently skips it, so it never renders.`),hint:`Fix the field name, or add "${n.name}" to ${t}. References must match the object's field names exactly.`+(s.size>0?` Object fields: ${[...s].sort().join(`, `)}.`:``)})}return o}function ns(e){let t=[];if(!e||typeof e!=`object`)return t;let n=es(e),r=wt(e),i=Vo(e),a=w(e.pages);for(let e=0;e<a.length;e++){let o=a[e];if(!o||typeof o!=`object`)continue;let s=A(o.name)??`#${e}`,c=(e,i,a)=>{t.push(...ts(e,i,n,a,`skipped`,r))};for(let{component:n,path:r,objectName:a}of Ro(o,`pages[${e}]`)){let e=A(n.type),o=qo(n.properties)?n.properties:void 0;if(!e||!o)continue;let l=`page "${s}" \xB7 ${e}`,u=`${r}.properties`;if(e===Xo){let e=$o(o,u);c(e.related,e.relatedObject,l),c(e.parent,a,l),c(e.picker,e.pickerObject,l);continue}let d=Zo(e,o,u);d&&(c(d,a,l),t.push(...Uo(Qo(e,o,u)??[],a,i,l,Ko)))}let l=qo(o.interfaceConfig)?o.interfaceConfig:void 0;if(l){let t=A(l.source)??A(o.object),n=`pages[${e}].interfaceConfig`,r=[...j(l.columns,`${n}.columns`),...Jo(l.sort,`${n}.sort`),...j(l.filterBy,`${n}.filterBy`)],i=qo(l.userFilters)?l.userFilters:void 0;i&&r.push(...j(i.fields,`${n}.userFilters.fields`)),c(r,t,`page "${s}" \xB7 interfaceConfig`)}}return t}var rs=e=>!!e&&typeof e==`object`&&!Array.isArray(e),is=(e,t)=>{let n=e;for(let e of t){if(!rs(n)&&!Array.isArray(n))return;n=n[e]}return n},as=e=>{let t;try{t=JSON.stringify(e)??String(e)}catch{t=String(e)}return t.length>80?`${t.slice(0,77)}\u2026`:t};function os(e,t,n=0){let r=n===0?is(t,e.path):void 0,i=n>0||e.code===`custom`||e.message.includes(`received `)?``:r===void 0?` (nothing is set there)`:` (received ${as(r)})`,a=e.code===`invalid_union`?e.errors:void 0;if(!a||a.length===0)return`${e.message}${i}`;let o=a.map(e=>e.map(e=>`${e.path.length?`${e.path.join(`.`)} \u2014 `:``}${os(e,t,n+1)}`).join(`; `)).filter(e=>e.length>0);return o.length===0?`${e.message}${i}`:`${e.message}${i} \u2014 no accepted form matched: `+o.map((e,t)=>`(${t+1}) ${e}`).join(` `)}var ss=null;function cs(){if(ss)return ss;let e=import.meta.url?import.meta.url:typeof __filename<`u`?__filename:process.cwd()+`/`;try{ss=(0,C.createRequire)(e)(`typescript`)}catch(e){throw Error(`@objectstack/lint: validating a kind:'react' page requires the "typescript" package, which could not be loaded (${e instanceof Error?e.message:String(e)}). It is a declared dependency of @objectstack/lint \u2014 if this deployment prunes packages, keep "typescript" in the image; it is only loaded when a react-source page is validated.`)}return ss}var ls=new Map(at.map(e=>[e.tag,{requiredBindings:e.interactions.filter(e=>e.required).map(e=>e.name),knownProps:new Set(e.interactions.map(e=>e.name)),deprecated:new Map(e.interactions.filter(e=>e.deprecated).map(e=>[e.name,e.deprecated])),retired:new Map(Object.entries(rt[e.tag]??{})),requiredDescriptions:new Map(e.interactions.filter(e=>e.required).map(e=>[e.name,e.description]))}]));function us(e,t,n=2){if(Math.abs(e.length-t.length)>n)return n+1;let r=Array.from({length:e.length+1},(e,t)=>t);for(let n=1;n<=t.length;n++){let i=r[0];r[0]=n;for(let a=1;a<=e.length;a++){let o=r[a];r[a]=Math.min(r[a]+1,r[a-1]+1,i+(e[a-1]===t[n-1]?0:1)),i=o}}return r[e.length]}function ds(e,t){if(t.has(e))return null;let n=null,r=3;for(let i of t){let t=us(e,i);t<r&&(r=t,n=i)}return r<=2?n:null}var M=Symbol(`not-static`);function fs(e,t,n){if(!n)return M;if(e.isParenthesizedExpression(n))return fs(e,t,n.expression);if(e.isStringLiteral(n)||e.isNoSubstitutionTemplateLiteral(n))return n.text;if(e.isNumericLiteral(n))return Number(n.text);if(n.kind===e.SyntaxKind.TrueKeyword)return!0;if(n.kind===e.SyntaxKind.FalseKeyword)return!1;if(n.kind===e.SyntaxKind.NullKeyword)return null;if(e.isArrayLiteralExpression(n)){let r=[];for(let i of n.elements){let n=fs(e,t,i);if(n===M)return M;r.push(n)}return r}if(e.isObjectLiteralExpression(n)){let r={};for(let i of n.properties){if(!e.isPropertyAssignment(i))return M;let n=e.isIdentifier(i.name)||e.isStringLiteral(i.name)?i.name.text:null;if(n===null)return M;let a=fs(e,t,i.initializer);if(a===M)return M;r[n]=a}return r}return M}function ps(e,t,n){let r=n.initializer;return r?e.isStringLiteral(r)?r.text:e.isJsxExpression(r)?fs(e,t,r.expression):M:!0}function ms(e,t,n){let r=n.initializer;if(!r||!e.isJsxExpression(r))return M;let i=n=>n?e.isParenthesizedExpression(n)?i(n.expression):e.isArrayLiteralExpression(n)?n.elements.map(e=>i(e)):fs(e,t,n):M;return i(r.expression)}var hs=`react-page-source-unparseable`,gs=`react-prop-deprecated`,_s=`react-prop-retired`,vs=`react-chart-field-unknown`,ys=`react-chart-field-unprovisioned`,bs=`react-chart-aggregate-invalid`,xs=`react-chart-axis-unknown`,Ss=`react-chart-drilldown-invalid`;function Cs(e,t){if(e===void 0||e===M)return;if(!N(e)){t(`error`,Ss,`drillDown must be a configuration object, not ${Array.isArray(e)?`an array`:typeof e}.`,`Write drillDown={{ … }} — or, to turn the drill on with all defaults, drillDown={{}}. Omit the prop entirely to leave drill off.`);return}let n=ne.safeParse(e);if(!n.success)for(let e of n.error.issues)t(`error`,Ss,`${e.path.length?`drillDown.${e.path.join(`.`)}`:`drillDown`}: ${e.message}`,`The drill config is declared by ChartDrillDownSchema (@objectstack/spec/ui) — the rejection above carries the fix.`)}function ws(e,t){if(e===void 0||e===M)return;if(!N(e)){t(`error`,bs,`aggregate must be a configuration object, not ${Array.isArray(e)?`an array`:typeof e}.`,`Write aggregate={{ function: "count", groupBy: "<field>" }} — or bind data={…} instead to chart precomputed rows.`);return}let n=e.groupBy===void 0;n&&t(`warning`,bs,`aggregate.groupBy is not set, so the aggregate returns ONE ungrouped row and the chart plots a single point.`,`Add aggregate.groupBy (a field name, or { field, dateGranularity } to bucket dates) to give the chart a category axis. objectstack#5583 ruled that an ungrouped single-value chart is NOT a supported <ObjectChart> shape — groupBy stays required, and a single number belongs in an object-metric block instead. This stays a warning rather than an error only because promoting it is its own step.`);let r=i.safeParse(e);if(!r.success)for(let i of r.error.issues)n&&i.path[0]===`groupBy`||t(`error`,bs,`${i.path.length?`aggregate.${i.path.join(`.`)}`:`aggregate`}: ${os(i,e)}`,`The aggregate is declared by ChartAggregateSchema (@objectstack/spec/ui) — the rejection above carries the fix.`)}var N=e=>!!e&&typeof e==`object`&&!Array.isArray(e),P=e=>typeof e==`string`&&e.length>0?e:void 0;function Ts(e,t,n,r=new Map){let{values:i,where:a,path:o}=e,s=(e,t,r,i)=>n.push({severity:e,rule:t,where:a,path:o,message:r,hint:i});if(Cs(i.get(`drillDown`),s),i.has(`data`))return;let c=i.get(`aggregate`);if(ws(c,s),c===void 0||c===M||!N(c))return;let l=P(c.function),u=P(c.field),d=c.groupBy,f=P(d)??(N(d)?P(d.field):void 0),p=P(i.get(`objectName`)),m=p?t.get(p):void 0;if(p&&m){let e=r.get(p),t=(t,n)=>{if(t&&!t.includes(`.`)){if(m.has(t)||bt.has(t)){e?.has(t)&&s(`warning`,ys,`aggregate.${n} "${t}" resolves on object "${p}", but ${Tt(p,t)} \u2014 the aggregate query reads a column that is empty on every row, so the chart ${n===`groupBy`?`groups everything into one empty bucket`:`aggregates nothing`} instead of failing.`,Et(p,t));return}s(`error`,vs,`aggregate.${n} "${t}" is not a field on object "${p}" \u2014 the aggregate query has nothing to ${n===`groupBy`?`group by`:`aggregate`}, so the chart comes back empty.`,`Fix the field name, or add "${t}" to ${p}.`+(m.size>0?` Object fields: ${[...m].sort().join(`, `)}.`:``))}};t(u,`field`),t(f,`groupBy`)}let h=ut({field:u,function:l,groupBy:d}),g=[h.category,h.value].filter(e=>!!e);if(g.length===0)return;let _=(e,t)=>{e&&(g.includes(e)||h.comparison&&e===h.comparison||s(`error`,xs,`"${e}" is not a column this aggregate returns, so the axis plots nothing. Object-bound aggregate rows are keyed by the RAW FIELD NAMES (unlike a dataset, whose rows are keyed by measure name).`,`Result columns: ${g.join(`, `)}`+(h.comparison?` (plus "${h.comparison}" with a comparison overlay)`:``)+`. Bind ${t} to one of them.`))},v=i.get(`xAxis`),y=P(i.get(`xAxisKey`))??P(v)??(N(v)?P(v.field):void 0),b=i.has(`xAxisKey`)?`xAxisKey`:`xAxis.field`;_(y,b);let ee=i.get(`yAxis`),x=Array.isArray(ee)?ee:ee===void 0?[]:[ee];for(let e of x)_(P(e)??(N(e)?P(e.field):void 0),`yAxis[].field`);let te=i.get(`series`);if(Array.isArray(te))for(let e of te){if(!N(e))continue;let t=P(e.dataKey);_(t??P(e.name),t?`series[].dataKey`:`series[].name`)}y&&h.category&&y!==h.category&&y===h.value&&s(`error`,xs,`${b} "${y}" is the aggregate's VALUE column, not its category column.`,`The category axis is keyed by groupBy \u2014 bind it to "${h.category}".`)}var Es={ListView:{fields:[`fields`,`columns`,`hiddenFields`,`fieldOrder`,`filterableFields`],sorts:[`sort`],nestedFields:[`userFilters`,`grouping`],filterArrays:[`filters`]},ObjectForm:{fields:[`fields`],keyedByField:[`initialValues`],sections:[`sections`,`groups`]},ObjectChart:{filterArrays:[`filter`]}},Ds=` › `,Os=new Map(at.map(e=>[e.tag,e.schemaType])),ks=new Set(Object.values(Es).flatMap(e=>e.filterArrays??[]));function As(e){let t={};for(let[n,r]of e)r!==M&&(t[n]=r);return t}function js(e,t){let n=[],r=[];if(!Array.isArray(e))return{child:n,parent:r};for(let i=0;i<e.length;i++){let a=e[i];if(!N(a))continue;let o=e=>`${t}[${i}].${e}`;n.push({objectName:P(a.childObject),refs:[...j(a.columns,o(`columns`)),...j(a.relationshipField,o(`relationshipField`)),...j(a.amountField,o(`amountField`))]}),r.push(...j(a.totalField,o(`totalField`)))}return{child:n,parent:r}}function Ms(e,t,n){if(!Array.isArray(e)||e.length===0)return;let r=e[0];if(typeof r==`string`&&(r.toLowerCase()===`and`||r.toLowerCase()===`or`)){for(let r=1;r<e.length;r++)Ms(e[r],`${t}[${r}]`,n);return}if(Array.isArray(r)){for(let r=0;r<e.length;r++)Ms(e[r],`${t}[${r}]`,n);return}typeof r==`string`&&r.length>0&&e.length>=2&&typeof e[1]==`string`&&h.has(e[1].toLowerCase())&&n.push({name:r,path:`${t}[0]`})}function Ns(e,t,n){let r=[],i=[],a=e=>{let n=t.get(e);return n===M?void 0:n},o=e=>`${n}${Ds}${e}`;for(let t of e.fields??[])r.push(...j(a(t),o(t)));for(let t of e.sorts??[])r.push(...Jo(a(t),o(t)));for(let t of e.nestedFields??[]){let e=a(t);N(e)&&r.push(...j(e.fields,o(`${t}.fields`)))}for(let t of e.sections??[]){let e=a(t);if(Array.isArray(e))for(let n=0;n<e.length;n++){let i=e[n];N(i)&&r.push(...j(i.fields,o(`${t}[${n}].fields`)))}}for(let t of e.keyedByField??[]){let e=a(t);if(N(e))for(let n of Object.keys(e))r.push({name:n,path:o(`${t}.${n}`)})}for(let n of e.filterArrays??[])Ms(t.get(n),o(n),i);return{own:r,queried:i}}function Ps(e,t){if(e!==`ListView`)return P(t.get(`objectName`));let n=t.get(`data`);return N(n)&&n.provider===`object`?P(n.object):void 0}function Fs(e,t,n,r,i,a){let o=Ps(e,t),s=[],c=Es[e];if(c){let{own:e,queried:l}=Ns(c,t,i);s.push(...ts(e,o,n,r,`skipped`,a)),s.push(...ts(l,o,n,r,`queried`,a))}if(e===`ObjectForm`){let e=t.get(`subforms`),c=js(e===M?void 0:e,`${i}${Ds}subforms`);for(let e of c.child)s.push(...ts(e.refs,e.objectName,n,r,`skipped`,a));s.push(...ts(c.parent,o,n,r,`skipped`,a))}let l=e===`Block`?P(t.get(`type`)):Os.get(e);return l&&Yo[l]&&s.push(...ts(Zo(l,As(t),i,Ds)??[],o,n,r,`skipped`,a)),s}var Is=`react-block-needs-record-context`,Ls="author the page as `type:'record'` — a record page mounts the record context these blocks render from.";function Rs(e,t,n,r){return{severity:`error`,rule:Is,where:n,path:r,message:`<${e}> renders "${t}", which reads its record from the record context a record page mounts \u2014 a kind:'react' page never mounts one, so the block renders empty no matter how it is bound (its objectName/recordId are not read by the renderer).`,hint:`On a react page bind the record yourself: ${Je[t]??Ls}`}}function zs(e,t){let n=new Set,r=t=>{(e.isFunctionDeclaration(t)&&t.name||e.isVariableDeclaration(t)&&e.isIdentifier(t.name)||e.isImportSpecifier(t))&&n.add(t.name.text),e.forEachChild(t,r)};return r(t),n}function Bs(e){let t=[],n=es(e),r=wt(e),i=Ao(e);for(let{rec:a,path:o}of D(e.pages,`pages`)){if(!a||a.kind!==`react`)continue;let e=a.source;if(typeof e!=`string`||e.trim()===``)continue;let s=String(a.name??o),c=cs(),{sourceFile:l,failure:u}=yr(c,`page.tsx`,e,{target:c.ScriptTarget.Latest,setParentNodes:!0,scriptKind:c.ScriptKind.TSX});u&&t.push({severity:`warning`,rule:hs,where:`page "${s}"`,path:`${o}.source`,message:`kind:'react' source did not parse (${br(u)}), so the component-contract checks read a partially recovered tree and may have missed real problems.`,hint:xr});let d=zs(c,l),f=e=>{if(c.isJsxOpeningElement(e)||c.isJsxSelfClosingElement(e)){let a=e.tagName.getText(l),u=`page "${s}" \u203A <${a}>`,p=`${o}.source`,m=Re.get(a);if(m&&!d.has(a)){t.push(Rs(a,m,u,p)),c.forEachChild(e,f);return}let h=ls.get(a);if(h){let o=!1,s=new Set,d=new Map;for(let t of e.attributes.properties){if(c.isJsxSpreadAttribute(t)){o=!0;continue}if(c.isJsxAttribute(t)){let e=t.name.getText(l);s.add(e),d.set(e,ks.has(e)?ms(c,l,t):ps(c,l,t))}}if(a===`Block`){let n=P(d.get(`type`));if(n&&Ve(n)){t.push(Rs(a,n,u,p)),c.forEachChild(e,f);return}}if(!o)for(let e of h.requiredBindings){if(s.has(e))continue;let n=h.deprecated.get(e);n&&s.has(n.replacedBy)||[...s].some(t=>h.retired.get(t)?.replacedBy===e)||t.push({severity:`error`,rule:`react-prop-missing-required`,where:u,path:p,message:n?`<${a}> is missing its "${e}" binding \u2014 pass ${n.replacedBy}={\u2026} (canonical) or ${e}={\u2026} (deprecated).`:`<${a}> is missing the required prop "${e}".`,hint:n?n.note:h.requiredDescriptions.get(e)??`Pass ${e}={\u2026}. See the react-tier component contract.`})}for(let e of s){let n=h.retired.get(e);if(n){t.push({severity:`error`,rule:_s,where:u,path:p,message:`<${a}> prop "${e}" is retired \u2014 the contract's only spelling is "${n.replacedBy}".`,hint:n.note});continue}let r=h.deprecated.get(e);r&&t.push({severity:`warning`,rule:gs,where:u,path:p,message:`<${a}> prop "${e}" is the deprecated spelling of the metadata-tier "${r.replacedBy}" and is removed after the deprecation window (#11284).`,hint:r.note});let i=ds(e,h.knownProps);i&&t.push({severity:`warning`,rule:`react-prop-typo`,where:u,path:p,message:`<${a}> has prop "${e}" \u2014 did you mean "${i}"?`,hint:`Likely a typo of a contract prop. Fix it or remove it.`})}a===`ObjectChart`&&!o&&Ts({values:d,where:u,path:p},n,t,r),a===`ListView`&&!o&&t.push(...jo(d.get(`searchableFields`),Ps(a,d),i,u,`${p} \u203A searchableFields`,`searchableFields`,`narrowing`,r)),o||t.push(...Fs(a,d,n,u,p,r))}}c.forEachChild(e,f)};f(l)}return t}var Vs=`page-source-className-tailwind`,Hs=/\bclassName\s*=\s*["'{]/g;function Us(e){let t=[];for(let{rec:n,path:r}of D(e.pages,`pages`)){if(!n)continue;let e=n.kind;if(e!==`html`&&e!==`react`&&e!==`jsx`)continue;let i=n.source;if(typeof i!=`string`||i.trim()===``)continue;let a=String(n.name??r);Hs.lastIndex=0;let o=0;for(;Hs.exec(i)!==null;)o++;o!==0&&t.push({severity:`warning`,rule:Vs,where:`page "${a}"`,path:`${r}.source`,message:`${o} \`className\` attribute${o>1?`s`:``} in ${String(e)}-source page \u2014 Tailwind utilities in page source silently produce no CSS (the build never scans authored metadata; ADR-0065).`,hint:e===`react`?`Style with inline style={{}} using hsl(var(--token)) theme colors (e.g. color:'hsl(var(--foreground))', background:'hsl(var(--card))'); render drawer/modal via <ObjectForm formType="drawer"|"modal"> instead of hand-rolled overlays.`:`Lay out with the components' structured props (<flex direction gap>, <grid columns>) and add CSS via a JSON style object style={{"color":"hsl(var(--foreground))"}}; do not use Tailwind className.`})}return t}var Ws=`title-format-retired`,Gs=`title-unresolvable`;function Ks(e){let t=[],n=w(e.objects);for(let e=0;e<n.length;e++){let r=n[e],i=typeof r.name==`string`?r.name:`(object ${e})`,a=`object "${i}"`,o=`objects[${e}]`;r.titleFormat!==void 0&&r.titleFormat!==null&&r.titleFormat!==``&&t.push({severity:`warning`,rule:Ws,where:a,path:o,message:`${i}: titleFormat is retired (ADR-0079) \u2014 migrate to nameField (single field) or a formula field designated nameField`,hint:`titleFormat is a render-only template the server cannot return or query, and an explicit nameField now takes precedence. For a single-field title set nameField: '<field>'. For a composite title, add a formula field (returnType: 'text') and designate it via nameField.`}),Ge(r).status===`none`&&t.push({severity:`warning`,rule:Gs,where:a,path:o,message:`${i}: no resolvable record title \u2014 records will have no meaningful name (no nameField and no title-eligible field to derive one)`,hint:`Set nameField to a text/email field (or a formula field with returnType: 'text'), or add a text field named "name"/"title". The runtime auto-provisions a primary and falls back to "Record #<id>", but an explicit title is far more useful.`})}return t}var qs=`field-group-undeclared`,Js=`field-group-empty`,Ys=`field-group-shadowed`,Xs=`semantic-role-field-unknown`,Zs=`semantic-role-field-unprovisioned`;function Qs(e){let t=[],n=w(e.objects);for(let e=0;e<n.length;e++){let r=n[e];if(!r||typeof r!=`object`)continue;let i=typeof r.name==`string`?r.name:`(object ${e})`,a=`object "${i}"`,o=`objects[${e}]`,s=r.fields&&typeof r.fields==`object`&&!Array.isArray(r.fields)?r.fields:{},c=new Set([...Object.keys(s),...xt(r)]),l=St(r),u=(e,t)=>({severity:`warning`,rule:Zs,where:a,path:`${o}.${e}`,message:`${i}: ${e} points at "${t}", an injected system column with no storage behind it \u2014 this object is external (ADR-0015), so the platform registers the anchor but the remote schema owns the table and no column backs it. Every consumer renders it empty on every record.`,hint:`If the remote table really carries "${t}", declare it in the object's own fields (mapped through the external binding's columnMap); otherwise point ${e} at a real remote column.`}),d=new Set((Array.isArray(r.fieldGroups)?r.fieldGroups:[]).filter(e=>!!e&&typeof e==`object`).map(e=>e.key).filter(e=>typeof e==`string`&&e.length>0)),f=new Set;for(let[e,n]of Object.entries(s)){let r=n?.group;typeof r==`string`&&r.length!==0&&(f.add(r),d.has(r)||t.push({severity:`warning`,rule:qs,where:a,path:`${o}.fields.${e}.group`,message:`${i}.${e}: group "${r}" is not declared in fieldGroups \u2014 the field renders in the ungrouped bucket, not under "${r}"`,hint:`Declare { key: '${r}', label: '\u2026' } in ${i}.fieldGroups, or fix the field's group reference. Group keys are snake_case and must match exactly.`}))}for(let e of d)f.has(e)||t.push({severity:`warning`,rule:Js,where:a,path:`${o}.fieldGroups`,message:`${i}: fieldGroups declares "${e}" but no field references it \u2014 the group never renders`,hint:`Assign at least one field via group: '${e}', or remove the unused group declaration.`});let p=r.stageField;typeof p==`string`&&p.length>0&&!c.has(p)?t.push({severity:`warning`,rule:Xs,where:a,path:`${o}.stageField`,message:`${i}: stageField "${p}" is not a field on this object \u2014 consumers fall back to heuristic stage detection`,hint:`Point stageField at an existing select/status field, or set stageField: false to declare the object has no linear lifecycle.`}):typeof p==`string`&&l.has(p)&&t.push(u(`stageField`,p));let m=Array.isArray(r.highlightFields)?r.highlightFields:Array.isArray(r.compactLayout)?r.compactLayout:[];for(let e of m)typeof e==`string`&&e.length!==0&&c.has(e)&&l.has(e)&&t.push(u(`highlightFields`,e));let h=m.filter(e=>typeof e==`string`&&e.length>0);if(h.length>0&&d.size>0){let e=[r.nameField,r.displayNameField].find(e=>typeof e==`string`&&e.length>0&&c.has(e))??[`name`,`full_name`,`title`,`subject`,`display_name`].find(e=>c.has(e)),n=new Set(h.filter(t=>t!==e).slice(0,4)),l=new Set(n);e&&l.add(e);for(let e of d){let n=Object.entries(s).filter(([,t])=>t?.group===e&&t?.hidden!==!0).map(([e])=>e);n.length!==0&&n.every(e=>l.has(e))&&t.push({severity:`warning`,rule:Ys,where:a,path:`${o}.fieldGroups`,message:`${i}: every field in group "${e}" (${n.join(`, `)}) is hoisted into the detail highlight strip (or is the record title) \u2014 the group renders on forms but never on detail pages`,hint:`Keep at least one non-highlighted field in "${e}", or remove the group if the strip already covers it. (Detail pages show the first 4 highlightFields as the top strip and hide them from the body.)`})}}}return t}function $s(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function ec(e){return typeof e==`string`&&e.length>0?e:void 0}function tc(e){return ec(e.objectName)??ec(e.object)??($s(e.data)?ec(e.data.object):void 0)}function nc(e,t){if(!$s(e))return[];let n=[{view:e,path:t,surface:``,kind:`self`}];$s(e.form)&&n.push({view:e.form,path:`${t}.form`,surface:`form`,kind:`form`});for(let r of[`listViews`,`formViews`]){let i=e[r];if(!$s(i))continue;let a=r===`listViews`?`listView`:`formView`;for(let[e,o]of Object.entries(i))$s(o)&&n.push({view:o,path:`${t}.${r}.${e}`,surface:`${r}.${e}`,kind:a})}return n}function rc(e,t){return nc(e,t).filter(e=>e.kind!==`listView`)}var ic=`form-field-unknown`,ac=`absolute-colspan-discouraged`,oc=`form-section-group-unknown`;function sc(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function cc(e){return typeof e==`string`&&e.length>0?e:void 0}function lc(e){if(typeof e==`string`)return e.length>0?e:null;if(e&&typeof e==`object`&&!Array.isArray(e)){let t=e.field;return typeof t==`string`&&t.length>0?t:null}return null}function uc(e){let t=[],n=new Map;for(let t of w(e.objects)){let e=typeof t.name==`string`?t.name:void 0;if(!e)continue;let r=t.fields&&typeof t.fields==`object`&&!Array.isArray(t.fields)?Object.keys(t.fields):[];n.set(e,new Set(r))}let r=Vo(e);for(let{rec:i,path:a}of D(e.views,`views`)){let e=cc(i.name)??cc(i.object)??a,o=tc(i),s=sc(i.list)?tc(i.list)??o:void 0;for(let c of rc(i,a)){let i=tc(c.view)??o??s,a=i?n.get(i):void 0,l=c.surface?`view "${e}" \xB7 ${c.surface}`:`view "${e}"`;for(let n of[`sections`,`groups`]){let o=Array.isArray(c.view[n])?c.view[n]:[];t.push(...Uo(Ho(o,`${c.path}.${n}`),i,r,l,oc));for(let r=0;r<o.length;r++){let s=o[r],u=sc(s)&&Array.isArray(s.fields)?s.fields:[];for(let o=0;o<u.length;o++){let s=u[o],d=lc(s),f=`${c.path}.${n}[${r}].fields[${o}]`;d&&a&&!a.has(d)&&t.push({severity:`warning`,rule:ic,where:l,path:f,message:`${e}: field "${d}" is not a field on object "${i}" \u2014 it is silently skipped and never renders on the form`,hint:`Fix the field name, or add "${d}" to ${i}. Section field references must match the object's field names exactly.`});let p=sc(s)?s.colSpan:void 0;p!=null&&t.push({severity:`warning`,rule:ac,where:l,path:`${f}.colSpan`,message:`${e}: field "${d??`?`}" sets absolute colSpan ${String(p)} \u2014 the form's column count is derived per surface (mobile 1 / modal 2 / page 3-4), so a fixed span only aligns at one width`,hint:`Prefer span: 'full' (whole row at any column count), or omit for auto width. The renderer clamps colSpan to the current column count.`})}}}}}return t}function dc(e){return!!e&&typeof e==`object`&&typeof e.op==`string`}var fc=new Set([`==`,`!=`]),pc=new Set([`all`,`exists`,`exists_one`,`map`,`filter`]);function mc(e){return dc(e)&&e.op===`id`&&typeof e.args==`string`?e.args:null}function hc(e){let t=new Set,n=new Set,r=(e,i)=>{if(Array.isArray(e)){for(let t of e)r(t,i);return}if(!dc(e))return;let a=e.args;if(e.op===`rcall`&&Array.isArray(a)&&typeof a[0]==`string`&&pc.has(a[0])){r(a[1],i),r(a[2],!1);return}if(typeof e.op==`string`&&fc.has(e.op)&&Array.isArray(a)&&a.length===2){let e=i?mc(a[1]):null;if(r(a[0],i),e!==null){t.add(e);return}r(a[1],i);return}let o=mc(e);if(o!==null){n.add(o);return}r(a,i)};r(e,!0);for(let e of n)t.delete(e);return t}function gc(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function _c(e){let t=e.data;if(gc(t)&&t.provider===`schema`)return typeof t.schemaId==`string`?t.schemaId:void 0}var vc=`visibility-root-mislayered`,yc=`visibility-bare-identifier`,bc=`visibility-predicate-syntax`,xc=`visibility-predicate-over-budget`,Sc=`visibility-predicate-unknown-function`,Cc=`visibleWhen`;function wc(e){if(typeof e==`string`)return e;if(e&&typeof e==`object`&&typeof e.source==`string`)return e.source}function Tc(e,t){return RegExp(`(^|[^.\\w$])${t}\\.\\w`).test(e)}function Ec(e){return e.replace(/'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"/g,e=>` `.repeat(e.length))}var Dc=[{wrote:`===`,cel:`==`,example:`record.country == 'USA'`,re:/===/},{wrote:`!==`,cel:`!=`,example:`record.country != 'USA'`,re:/!==/},{wrote:`<>`,cel:`!=`,example:`record.country != 'USA'`,re:/<>/},{wrote:`and`,cel:`&&`,example:`record.a == 1 && record.b == 2`,re:/(?<![.\w$])and(?![\w$])/i},{wrote:`or`,cel:`||`,example:`record.a == 1 || record.b == 2`,re:/(?<![.\w$])or(?![\w$])/i},{wrote:`not`,cel:`!`,example:`!record.archived`,re:/(?<![.\w$])not(?![\w$])/i},{wrote:`=`,cel:`==`,example:`record.status == 'open'`,re:/(?<![=!<>])=(?!=)/}];function Oc(e){let t=e.replace(/\s+/g,` `).trim();return t.length>120?`${t.slice(0,117)}...`:t}function kc(e){if(!e.trim())return null;let t=Te(e);if(t.ok||t.kind===`empty`)return null;if(t.kind===`bounds`)return{kind:`bounds`,overrun:t.overrun};let n=Oe(e),r=n.ok?`the expression could not be parsed`:n.error.split(`
|
|
5
|
-
`)[0].trim(),i=Ec(e);return{kind:`syntax`,detail:r,token:Dc.find(e=>e.re.test(i))??null}}function Ac(e){return e.limit&&e.limitValue!==null?`the \`${e.limit}\` budget (platform limit ${e.limitValue})`:`one of the platform's parse budgets`}var jc=[`current_user`,`page`];function Mc(e){return!!e&&typeof e==`object`&&typeof e.op==`string`}function Nc(e,t){if(Array.isArray(e)){for(let n of e)Nc(n,t);return}if(!Mc(e))return;let n=e.args;if(Array.isArray(n)){let r=e.op===`rcall`?n[1]:n[0];(e.op===`.`||e.op===`.?`||e.op===`[]`||e.op===`rcall`)&&Mc(r)&&r.op===`id`&&typeof r.args==`string`&&t.add(r.args)}Nc(n,t)}var Pc=`true`;function Fc(e,t,n){if(Array.isArray(e)){for(let r of e)if(!Fc(r,t,n))return!1;return!0}if(!Mc(e))return!0;let r=e.args;if(e.op===`call`&&Array.isArray(r)&&r[0]===`has`){let{start:r,end:i}=e;if(!Number.isInteger(r)||!Number.isInteger(i))return!1;let a=r,o=i;return a<0||o>t.length||o-a<Pc.length||!t.slice(a,o).startsWith(`has`)?!1:(n.push([a,o]),!0)}return Fc(r,t,n)}function Ic(e,t){let n=[];if(!Fc(t,e,n)||n.length===0)return e;let r=e;for(let[e,t]of n)r=r.slice(0,e)+Pc.padEnd(t-e,` `)+r.slice(t);return r}function Lc(e,t){let n=Ne(e);if(!n)return null;let r=new Set;Nc(n,r);let i=t?hc(n):[];return Ae(Ic(e,n),[...jc,...r,...i])}var Rc={runtime:`record`,metadata:`data`},zc={runtime:{forbiddenRoot:`data`,message:"visibility predicate is rooted at `data.` — that is the root a metadata-editing form binds (the row under edit), not a runtime surface. A runtime view/page predicate that binds `data.` never matches and the element renders unconditionally (ADR-0089).",hint:"Runtime record surfaces bind `record` + `current_user` (pages also expose `page.<var>`). Use e.g. `record.status == 'open'` instead of `data.status == 'open'`."},metadata:{forbiddenRoot:`record`,message:"visibility predicate is rooted at `record.` — that is the root a runtime view/page surface binds (the live record), not the root a metadata-editing form binds. On a metadata-editing form — the row under edit — a `record.`-rooted predicate never matches and the element renders unconditionally (ADR-0089).",hint:"Metadata-editing forms bind `data` (the row under edit). Use e.g. `data.type == 'grid'` instead of `record.type == 'grid'`."}};function Bc(e,t,n,r,i,a=!1){let o=wc(e[Cc]??e.visibleOn??e.visibility),s=zc[r];o&&Tc(o,s.forbiddenRoot)&&i.push({severity:`warning`,rule:vc,where:t,path:n,message:s.message,hint:s.hint});let c=o?kc(o):null;if(o&&c?.kind===`bounds`){let e=Ac(c.overrun),a=Rc[r];i.push({severity:`error`,rule:xc,where:t,path:n,message:`visibility predicate is syntactically valid CEL but overruns ${e} (${c.overrun.summary}) (predicate: \`${Oc(o)}\`). The canonical front end refuses it, so it can never evaluate, and the console falls OPEN: the element renders unconditionally and looks exactly like one with no predicate at all (#5149).`,hint:`There is no syntax or dialect error to correct here \u2014 this is a SIZE fault, not a dialect mistake, so re-spelling the predicate will not fix it. Make it smaller, or move the work off the predicate: (1) collapse a long \`${a}.f == 'a' || ${a}.f == 'b' || \u2026\` chain into a single \`${a}.f in ['a', 'b', \u2026]\`, which is far fewer AST nodes (\`maxListElements\` is 64, so a very large set needs option 2); (2) precompute the heavy part into a formula/rollup field on the object and test that one field instead. Logic genuinely this large is not element visibility \u2014 compute it once on the record rather than re-deriving it in every predicate that needs it.`})}o&&c?.kind===`syntax`&&i.push({severity:`error`,rule:bc,where:t,path:n,message:`visibility predicate is not valid CEL \u2014 ${c.detail} (predicate: \`${Oc(o)}\`). A predicate that does not parse can never evaluate, and the console falls OPEN: the element renders unconditionally and looks exactly like one with no predicate at all (#5149).`,hint:c.token?`\`${c.token.wrote}\` is not a CEL operator \u2014 CEL spells it \`${c.token.cel}\`. Replace \`${c.token.wrote}\` with \`${c.token.cel}\`, e.g. \`${c.token.example}\`.`:"Visibility predicates are bare CEL, e.g. `record.status == 'open'`. Spellings from other languages do not parse: write `==` (not `===`), `!=` (not `!==` or `<>`), `&&` (not `and`), `||` (not `or`), `!` (not `not`)."});let l=o&&!c?Me(o):null;if(o&&l&&i.push({severity:`error`,rule:Sc,where:t,path:n,message:`visibility predicate calls \`${l.name}\`, which the platform's CEL environment does not register \u2014 ${l.detail} (predicate: \`${Oc(o)}\`). The predicate parses, so nothing else reports it, and it faults the moment it is evaluated: on a view/page surface the console falls OPEN and the element renders unconditionally, exactly like one carrying no predicate at all; on an action surface \u2014 evaluated with \`throwOnError: true\` \u2014 it falls CLOSED and the action disappears for EVERY user, including one who holds the grant, leaving one deduped \`console.warn\` as the only signal.`,hint:`\`${l.name}\` is not a function this platform registers \u2014 a NAME fault, not a dialect mistake, so re-spelling the predicate will not fix it. The callable names advertised for authoring are the \`functions\` list \`introspectScope\` returns (\`CEL_STDLIB_FUNCTIONS\`): pick one of those, or precompute the value into a formula field on the object and test that field instead.`}),o&&!c){let e=Lc(o,a);if(e){let a=Rc[r];i.push({severity:`error`,rule:yc,where:t,path:n,message:`visibility predicate references \`${e}\` as a bare identifier. Values are bound under a namespace on this surface \u2014 they are never flattened to top level \u2014 so \`${e}\` resolves to nothing, the predicate can never evaluate, and the console falls OPEN: the element renders unconditionally and looks exactly like one with no predicate at all (#5149).`,hint:`Write \`${a}.${e}\` instead of \`${e}\``+(r===`runtime`?" (runtime view/page surfaces bind `record` + `current_user`; a page component also exposes page state as `page.<var>`).":" (a metadata-editing form binds the row under edit as `data`).")})}}}function Vc(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function Hc(e,t={}){let n=t.layer??`runtime`,r=[];for(let{rec:t,path:i}of D(e.views,`views`)){let e=typeof t.name==`string`?t.name:typeof t.object==`string`?t.object:i;for(let a of rc(t,i)){let t=a.surface?`view "${e}" \xB7 ${a.surface}`:`view "${e}"`,i=_c(a.view)!==void 0,o=i,s=i?`metadata`:n;for(let e of[`sections`,`groups`]){let n=Array.isArray(a.view[e])?a.view[e]:[];for(let i=0;i<n.length;i++){let c=n[i];if(!c||typeof c!=`object`)continue;let l=`${a.path}.${e}[${i}]`;Bc(c,t,l,s,r,o);let u=Array.isArray(c.fields)?c.fields:[];for(let e=0;e<u.length;e++){let n=u[e];Vc(n)&&Bc(n,t,`${l}.fields[${e}]`,s,r,o)}}}}}for(let{rec:t,path:i}of D(e.pages,`pages`)){let e=`page "${(typeof t.name==`string`?t.name:void 0)??i}"`;for(let a of Ro(t,i))Bc(a.component,e,a.path,n,r)}return r}var Uc=`predicate-path-unresolved`,Wc=`predicate-path-unrooted`,Gc=`predicate-rhs-path-shaped`,Kc=[`visibleWhen`,`visibleOn`],F=`data`;function qc(e){if(!e||typeof e!=`object`&&typeof e!=`function`)return;let t=e;return t.def??t._def}function Jc(e,t=0){if(!e||t>25)return e;let n=qc(e);if(!n)return e;switch(n.type){case`optional`:case`nullable`:case`default`:case`prefault`:case`readonly`:case`catch`:case`nonoptional`:return Jc(n.innerType,t+1);case`lazy`:return Jc(n.getter(),t+1);case`pipe`:{let e=Jc(n.in,t+1);return qc(e)?.type===`transform`?Jc(n.out,t+1):e}default:return e}}function Yc(e){return Array.isArray(e?.options)?e.options:[]}function Xc(e,t=0){if(t>25)return null;let n=Jc(e),r=qc(n);if(r?.type===`object`)return Object.keys(r.shape??n.shape??{});if(r?.type===`union`||r?.type===`discriminated_union`){let e=new Set,n=!1;for(let i of Yc(r)){let r=Xc(i,t+1);if(r){n=!0;for(let t of r)e.add(t)}}return n?[...e]:null}if(r?.type===`intersection`){let e=Xc(r.left,t+1),n=Xc(r.right,t+1);return!e&&!n?null:[...new Set([...e??[],...n??[]])]}return null}function Zc(e,t,n=0){if(n>25)return;let r=Jc(e),i=qc(r);if(i?.type===`object`)return(i.shape??r.shape??{})[t];if(i?.type===`union`||i?.type===`discriminated_union`)for(let e of Yc(i)){let r=Zc(e,t,n+1);if(r!==void 0)return r}if(i?.type===`intersection`)return Zc(i.left,t,n+1)??Zc(i.right,t,n+1)}function Qc(e,t){let n=Zc(e,t);if(n===void 0)return;let r=Jc(n);for(let e=0;e<25;e++){let e=qc(r);if(e?.type===`array`)r=Jc(e.element);else if(e?.type===`record`)r=Jc(e.valueType);else return r}return r}function $c(e,t){let n=Jc(e),r=qc(n);if(r?.type===`record`)return{kind:`declared`,next:r.valueType};let i=Xc(n);return i===null?{kind:`opaque`}:i.includes(t)?{kind:`declared`,next:Zc(n,t)}:{kind:`undeclared`,declared:i}}function el(e){return!!e&&typeof e==`object`&&typeof e.op==`string`}function tl(e){if(!el(e))return null;if(e.op===`id`&&typeof e.args==`string`)return[e.args];if(e.op===`.`&&Array.isArray(e.args)&&typeof e.args[1]==`string`){let t=tl(e.args[0]);return t?[...t,e.args[1]]:null}return null}function nl(e,t){if(Array.isArray(e)){for(let n of e)nl(n,t);return}if(el(e)){if(e.op===`.`){let n=tl(e);if(n&&n[0]===F&&n.length>1){t.push(n.slice(1));return}}nl(e.args,t)}}var rl=/^[A-Za-z_$][A-Za-z0-9_$]*(?:\.[A-Za-z_$][A-Za-z0-9_$]*)*$/;function il(e,t){if(Array.isArray(e)){for(let n of e)il(n,t);return}if(!el(e))return;let n=e.args;if(e.op===`rcall`&&Array.isArray(n)&&typeof n[0]==`string`&&pc.has(n[0])){il(n[1],t);return}typeof e.op==`string`&&fc.has(e.op)&&Array.isArray(n)&&n.length===2&&t.push({op:e.op,right:n[1]}),il(n,t)}function al(e,t,n){if(Array.isArray(e)){for(let r of e)al(r,t,n);return}if(!el(e))return;let r=e.args;if(Array.isArray(r)){let t=e.op===`rcall`?r[1]:r[0];if((e.op===`.`||e.op===`.?`||e.op===`[]`||e.op===`rcall`)&&el(t)&&t.op===`id`&&typeof t.args==`string`&&n.add(t.args),e.op===`rcall`&&typeof r[0]==`string`&&pc.has(r[0])){let e=r[2];if(Array.isArray(e)&&e.length>=2){let t=e[0];el(t)&&t.op===`id`&&typeof t.args==`string`&&n.add(t.args)}}}if(e.op===`id`&&typeof e.args==`string`){t.add(e.args);return}al(r,t,n)}function ol(e){if(typeof e==`string`)return e;if(e&&typeof e==`object`&&typeof e.source==`string`)return e.source}function sl(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function cl(e,t,n,r,i){let a=Ne(e);if(!a)return;let o=[];nl(a,o);for(let e of o){let a=t,o=[];for(let t of e){let e=$c(a,t);if(e.kind===`opaque`)break;if(e.kind===`undeclared`){let a=[F,...o,t].join(`.`),s=o.length?`${F}.${o.join(`.`)}`:F;i.push({severity:`error`,rule:Uc,where:n,path:r,message:`predicate references \`${a}\`, which the target schema does not declare \u2014 \`${t}\` is not a key of \`${s}\`. The reference resolves to nothing, so the predicate can never evaluate and the console falls OPEN: the element renders unconditionally and looks exactly like one carrying no predicate at all (#5149).`,hint:`${be(_e(t,e.declared))||`\`${s}\` declares: ${e.declared.slice(0,12).sort().join(`, `)}`} Every reference must resolve against the schema the form edits.`});break}o.push(t),a=e.next}}let s=Xc(t),c=hc(a);if(s){let e=new Set,t=new Set;al(a,e,t);for(let a of e)t.has(a)||c.has(a)||!s.includes(a)||i.push({severity:`error`,rule:Wc,where:n,path:r,message:`predicate references \`${a}\` as a bare identifier, but \`${a}\` is a key of the schema this form edits \u2014 the binding root was dropped. Values are bound under \`${F}\` and are never flattened to top level, so \`${a}\` resolves to nothing, the predicate can never evaluate and the console falls OPEN: the element renders unconditionally and looks exactly like one carrying no predicate at all (#5149, #6254).`,hint:`Write \`${F}.${a}\` instead of \`${a}\`. A metadata-editing form binds the row under edit as \`${F}\` at every depth \u2014 inside a repeater \`${F}\` is the ROW, but it is still spelled \`${F}\` (there is no implicit row scope).`})}let l=[];il(a,l);for(let{op:e,right:t}of l){let a=tl(t);if(!a)continue;let o=a.join(`.`);if(!rl.test(o))continue;let s=a.length>1;i.push({severity:s?`error`:`warning`,rule:Gc,where:n,path:r,message:s?`predicate compares against \`${o}\` on the RIGHT of \`${e}\`, which is a path but is not evaluated as one. A metadata-editing form resolves paths on the LEFT of \`${e}\` only; the right-hand side goes to the literal parser, so \`${o}\` is compared as the literal string "${o}". The verdict therefore does not depend on the right-hand path at all: \`a == ${o}\` is FALSE even when both sides hold the same value, and \`a != ${o}\` is correspondingly TRUE. An \`==\` written this way hides the element on every row, and nothing in the console says why (objectui#4049).`:`predicate compares against the unquoted word \`${o}\` on the RIGHT of \`${e}\`. The right-hand side of \`${e}\` is a literal, never a reference, so this is read as the literal string "${o}" \u2014 which is probably what you meant, and is why it appears to work. It is outside the declared subset all the same (\`path == 'literal'\`), and it stops working when this surface moves to the real CEL evaluator, where a bare \`${o}\` resolves to nothing (objectui#4049). The token also reads as a \`${F}.\` root someone dropped, so this one finding carries BOTH readings: which one you meant is the thing no linter can know, and it changes the fix (#7696).`,hint:s?`Two sanctioned spellings. (1) If you meant the TEXT, quote it: \`${e} '${o}'\`. (2) If you meant the PATH, restructure so the path is on the LEFT and a literal is on the right \u2014 comparing one path against another is outside the subset this surface renders, which is \`path == 'literal'\` / \`path != 'literal'\` and nothing wider. There is no third spelling that compares two paths here.`:`Two sanctioned spellings, and you must pick \u2014 they are not the same predicate. (1) If you meant the TEXT \`${o}\`, quote it: \`${e} '${o}'\`. That is what this renders as today, so it changes no behaviour and is the fix unless you know otherwise. (2) If you meant the FIELD \`${F}.${o}\`, move it to the LEFT and put a literal on the right, e.g. \`${F}.${o} == 'yes'\`. \u26D4 Do NOT simply add the root in place: \`${e} ${F}.${o}\` is a path on the RIGHT, which this surface parses as the literal string "${F}.${o}" \u2014 it is refused by this same rule at \`error\`, and it is FALSE on every row. The subset here is \`path == 'literal'\` and nothing wider.`})}}function ll(e,t,n,r,i,a){if(!(!Array.isArray(e)||a>12))for(let o=0;o<e.length;o++){let s=e[o];if(!sl(s))continue;let c=`${r}[${o}]`;for(let e of Kc){let r=ol(s[e]);if(r!==void 0&&r.trim()){cl(r,t,n,`${c}.${e}`,i);break}}if(Array.isArray(s.fields)&&s.fields.length>0&&typeof s.field==`string`){let e=t===void 0?void 0:Qc(t,s.field);ll(s.fields,e,n,`${c}.fields`,i,a+1)}}}function ul(e,t={}){let n=t.resolveSchema??(e=>Ye(e)),r=[];for(let{rec:t,path:i}of D(e.views,`views`)){let e=typeof t.name==`string`?t.name:typeof t.object==`string`?t.object:i;for(let a of rc(t,i)){let t=_c(a.view);if(!t)continue;let i;try{i=n(t)}catch{i=void 0}let o=a.surface?`view "${e}" \xB7 ${a.surface} (schema "${t}")`:`view "${e}" (schema "${t}")`;for(let e of[`sections`,`groups`]){let t=Array.isArray(a.view[e])?a.view[e]:[];for(let n=0;n<t.length;n++){let s=t[n];if(!sl(s))continue;let c=`${a.path}.${e}[${n}]`;for(let e of Kc){let t=ol(s[e]);if(t!==void 0&&t.trim()){cl(t,i,o,`${c}.${e}`,r);break}}ll(s.fields,i,o,`${c}.fields`,r,0)}}}}return r}var dl=`capability-reference-unknown`;function fl(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`&&e.length>0):[]}function pl(e){if(Array.isArray(e))return fl(e).map(e=>({cap:e}));if(e&&typeof e==`object`){let t=[];for(let[n,r]of Object.entries(e))for(let e of fl(r))t.push({cap:e,key:n});return t}return[]}function ml(e){let t=[];if(!e||typeof e!=`object`)return t;let n=new Set(ue);for(let t of w(e.capabilities))typeof t.name==`string`&&t.name.length>0&&n.add(t.name);for(let t of w(e.permissions))for(let e of fl(t.systemPermissions))n.add(e);for(let t of w(e.data))if(t.object===`sys_capability`)for(let e of Array.isArray(t.records)?t.records:[]){let t=e?.name;typeof t==`string`&&t.length>0&&n.add(t)}let r=(e,r,i)=>{n.has(e)||t.push({severity:`warning`,rule:dl,where:r,path:i,message:`requiredPermissions references capability "${e}" which is registered nowhere \u2014 no built-in capability, no permission set in this package grants it via systemPermissions, and no sys_capability seed declares it`,hint:`Fix the capability name, define it with defineCapability (stack.capabilities), declare it on a permission set’s systemPermissions, ship a sys_capability seed row, or ignore this if the capability is provided by another installed package (references fail closed at runtime).`})},i=w(e.objects);for(let e=0;e<i.length;e++){let t=i[e];if(!t||typeof t!=`object`)continue;let n=typeof t.name==`string`?t.name:`(object ${e})`,a=`objects[${e}]`;for(let{cap:e,key:i}of pl(t.requiredPermissions))r(e,`object "${n}"`,`${a}.requiredPermissions${i?`.${i}`:``}`);let o=w(t.fields);for(let e of o){let t=typeof e.name==`string`?e.name:`(field)`;for(let i of fl(e.requiredPermissions))r(i,`field "${n}.${t}"`,`${a}.fields.${t}.requiredPermissions`)}for(let[e,i]of w(t.actions).entries()){let t=typeof i.name==`string`?i.name:`(action ${e})`;for(let o of fl(i.requiredPermissions))r(o,`action "${n}.${t}"`,`${a}.actions[${e}].requiredPermissions`)}}for(let[t,n]of w(e.actions).entries()){let e=typeof n.name==`string`?n.name:`(action ${t})`;for(let i of fl(n.requiredPermissions))r(i,`action "${e}"`,`actions[${t}].requiredPermissions`)}let a=w(e.apps);for(let e=0;e<a.length;e++){let t=a[e];if(!t||typeof t!=`object`)continue;let n=typeof t.name==`string`?t.name:`(app ${e})`,i=(e,t)=>{if(!e||typeof e!=`object`)return;if(Array.isArray(e)){e.forEach((e,n)=>i(e,`${t}[${n}]`));return}let a=e;for(let e of fl(a.requiredPermissions))r(e,`app "${n}"`,`${t}.requiredPermissions`);a.navigation&&i(a.navigation,`${t}.navigation`),a.areas&&i(a.areas,`${t}.areas`),a.tabs&&i(a.tabs,`${t}.tabs`),a.children&&i(a.children,`${t}.children`),a.items&&i(a.items,`${t}.items`)};i(t,`apps[${e}]`)}return t}var hl=`approval-approver-not-membership-tier`,gl=`approval-approver-type-deprecated`,_l=`approval-approver-type-unknown`,vl=`approval-approver-type-unsupported`,yl=`approval-escalation-reassign-no-target`,bl=`approval-approvers-may-resolve-empty`,xl=`approval-expression-invalid`,Sl=`approval-expression-no-empty-policy`,Cl=`approval-decision-outputs-reserved`,wl=`approval-approver-cross-org-unsupported`,Tl=new Set([`current`,`trigger`,`vars`]),El=new Set([`decision`,`requestId`]),Dl=new Set([`position`,`team`,`department`]),Ol=new Set(_),kl=_.join(`/`),Al={business_unit:`department`,bu:`department`};function jl(e){let t=[];if(!e||typeof e!=`object`)return t;let n=w(e.flows),r=new Set(Pe.options);for(let e=0;e<n.length;e++){let i=n[e];if(!i||typeof i!=`object`)continue;let a=typeof i.name==`string`?i.name:`(flow ${e})`,o=wi(i,`flows[${e}]`);for(let e=0;e<o.length;e++){let{node:n,path:i}=o[e];if(!n||n.type!==`approval`)continue;let c=typeof n.id==`string`?n.id:`(node ${e})`,l=n.config??{},u=Array.isArray(l.approvers)?l.approvers:[],d=`flow "${a}" \xB7 node "${c}"`;for(let e=0;e<u.length;e++){let n=u[e];if(!n||typeof n!=`object`)continue;let a=typeof n.type==`string`?n.type:``,o=typeof n.value==`string`?n.value:``,s=`${i}.config.approvers[${e}]`;if(a&&!r.has(a)){let e=Al[a];t.push({severity:`warning`,rule:_l,where:d,path:`${s}.type`,message:`approver type '${a}' is not an ApproverType (${Pe.options.join(` | `)}).`,hint:e?`Use the spec value: { type: '${e}', value: '${o}' }.`:`Pick one of the spec values; unmapped types degrade to an inert '${a}:${o}' literal at runtime.`});continue}let c=ft(a);if(c===`expression`){let e=o.trim();if(!e)t.push({severity:`error`,rule:xl,where:d,path:`${s}.value`,message:`expression approver has an empty expression — the node fails at entry.`,hint:`Write a CEL expression over current.* (the record's live state at node entry), trigger.* (the submit-time snapshot) or vars.* (flow variables), e.g. current.approvers_dynamic or vars.approval_lead.picked_departments.`});else{let n=Oe(e);if(!n.ok)t.push({severity:`error`,rule:xl,where:d,path:`${s}.value`,message:`expression approver does not parse as CEL: ${n.error}.`,hint:`Approver expressions are bare CEL (no {…} template braces), e.g. current.approvers_dynamic or vars.get_reviewers.record.owner_id.`});else{let e=n.roots.filter(e=>!Tl.has(e));if(e.length){let n=e.includes(`record`)||e.includes(`previous`);t.push({severity:`error`,rule:xl,where:d,path:`${s}.value`,message:`expression approver references \`${e.join("`, `")}\` \u2014 only current.*, trigger.* and vars.* are available, and the node fails at entry on any other root.`,hint:n?'`record`/`previous` are not bound here (on this platform `record` always means "the record at event time", which is ambiguous at an approval node). Write current.<field> for the live value at node entry, trigger.<field> for the submit-time snapshot (vars.previous carries the pre-update row).':`Did you mean current.<field> (live record), trigger.<field> (submit snapshot), or vars.<name> (flow variable)?`})}}}}else n.resolveAs!=null&&t.push({severity:`info`,rule:xl,where:d,path:`${s}.resolveAs`,message:`resolveAs has no effect on a '${a}' approver \u2014 it only applies to type 'expression'.`,hint:`Remove it, or switch this approver to { type: 'expression', value: '<CEL>', resolveAs: '${String(n.resolveAs)}' }.`});if(c===`org_membership_level`&&o&&!Ol.has(o.toLowerCase()))t.push({severity:`warning`,rule:hl,where:d,path:`${s}.value`,message:`approver { type: '${a}', value: '${o}' } resolves against the better-auth org-membership tier (sys_member.role: ${kl}) \u2014 '${o}' is not a membership tier, so this approver matches nobody and the request stalls.`,hint:`If '${o}' is an org position, author { type: 'position', value: '${o}' } (resolved via sys_user_position, ADR-0090 D3). Keep type 'org_membership_level' only for membership tiers (${kl}) \u2014 the vocabulary is closed (ADR-0108), so a business role is always a position.`});else if(a in ct){let e=ft(a);t.push({severity:`warning`,rule:gl,where:d,path:`${s}.type`,message:`approver type '${a}' is the deprecated spelling of '${e}' (ADR-0090 D3) and is removed in the next major.`,hint:`Author { type: '${e}', value: '${o}' }. It resolves identically today.`})}else ke[c]?.source===`unsupported`&&t.push({severity:`warning`,rule:vl,where:d,path:`${s}.type`,message:`approver type '${a}' is declared but not implemented by the runtime (#3508) \u2014 the slot resolves to nobody and the request stalls.`,hint:`Route to people the engine can expand: { type: 'team' | 'department' | 'position', ... }. Queue approvers need a real ownership-queue implementation before they take effect.`});let l=n.organization;typeof l==`string`&&l.trim()!==``&&Pe.options.includes(c)&&!fe(c)&&t.push({severity:`error`,rule:wl,where:d,path:`${s}.organization`,message:`approver type '${a}' does not resolve through an organization directory, so 'organization: ${l}' has no effect (ADR-0105 D9) \u2014 the runtime refuses it.`,hint:`Drop 'organization' here. Cross-organization targeting applies to 'position', 'org_membership_level', 'department' and 'expression' approvers.`})}let f=u.filter(e=>e&&typeof e==`object`&&typeof e.type==`string`);if(f.length>0&&f.every(e=>Dl.has(ft(String(e.type))))){let e=l.lockRecord!==!1;t.push({severity:`info`,rule:bl,where:d,path:`${i}.config.approvers`,message:`every approver on this node routes to a group (position/team/department) whose members are runtime data — if none is staffed, the request resolves to an empty slate and waits forever`+(e?`, and (lockRecord) the record stays locked with no in-product recovery.`:`.`),hint:`Make sure at least one target is always staffed, or add a guaranteed-staffed fallback approver, e.g. { type: 'org_membership_level', value: 'owner' }. A request that still lands empty is recoverable only by a platform/tenant admin override (#3424).`})}u.some(e=>e&&typeof e==`object`&&ft(String(e.type??``))===`expression`)&&l.onEmptyApprovers==null&&t.push({severity:`info`,rule:Sl,where:d,path:`${i}.config`,message:`this node resolves approvers from an expression but declares no onEmptyApprovers — an empty result falls back to the default ('admin_rescue': request opens, only a privileged admin can act).`,hint:`Declare the empty-slate policy explicitly: onEmptyApprovers: 'admin_rescue' (hold for admin takeover), 'fail' (fail the node — config bug), or 'auto_approve' (wave through, output.autoApproved = true).`});let p=s(l.decisionOutputs).map(e=>e.key).filter(e=>El.has(e));p.length&&t.push({severity:`error`,rule:Cl,where:d,path:`${i}.config.decisionOutputs`,message:`decisionOutputs declares reserved key(s) \`${p.join("`, `")}\` \u2014 the resume envelope owns them, so every decide carrying them is rejected.`,hint:`Rename the output key(s); any name other than 'decision'/'requestId' works.`});let m=l.escalation??null;m&&typeof m==`object`&&m.action===`reassign`&&(typeof m.escalateTo==`string`&&m.escalateTo.trim()||t.push({severity:`warning`,rule:yl,where:d,path:`${i}.config.escalation.escalateTo`,message:`escalation.action is 'reassign' but escalateTo is empty — at runtime the escalation degrades to a notify and the request stays with the original approvers.`,hint:`Set escalateTo to a position machine name (expanded via sys_user_position, ADR-0090 D3) or a specific user id, or change action to 'notify'.`}))}}return t}var Ml=`seed-insert-mode-duplicates-on-replay`;function Nl(e){let t=[];return(Array.isArray(e.data)?e.data:[]).forEach((e,n)=>{if(!e||typeof e!=`object`||e.mode!==`insert`)return;let r=typeof e.object==`string`?e.object:void 0,i=r?`seed "${r}"`:`data[${n}]`;t.push({severity:`warning`,rule:Ml,where:i,path:`data[${n}].mode`,message:"`mode: 'insert'` re-inserts every record on each replay boot (dev-server restart, package re-publish) with no existing-row check, so the dataset duplicates the table on every restart — seeds are replayed, not applied once.",hint:"Use `mode: 'ignore'` (skip rows that already exist) or `'upsert'` (create-or-update), and declare an `externalId` to match on: a single natural-key field (e.g. `externalId: 'code'`), or a COMPOSITE list of fields for a join / junction table with no single natural key (e.g. `externalId: ['team', 'project']`)."})}),t}var Pl=`seed-value-outside-state-machine`;function Fl(e){let t=new Map;for(let n of e){if(!n||typeof n!=`object`)continue;let e=typeof n.name==`string`?n.name:void 0;if(!e)continue;let r=Array.isArray(n.validations)?n.validations:[],i=[];for(let e of r){if(!e||typeof e!=`object`||e.type!==`state_machine`)continue;let t=typeof e.field==`string`?e.field:void 0;if(!t)continue;let n=e.transitions&&typeof e.transitions==`object`?e.transitions:{},r=new Set;for(let t of Array.isArray(e.initialStates)?e.initialStates:[])r.add(String(t));for(let e of Object.keys(n)){r.add(String(e));let t=n[e];for(let e of Array.isArray(t)?t:[])r.add(String(e))}r.size>0&&i.push({field:t,states:r})}i.length>0&&t.set(e,i)}return t}function Il(e,t,n){let r=(Array.isArray(t)?t.map(String):typeof t==`string`?[t]:[`name`]).map(t=>e[t]).filter(e=>e!=null&&e!==``);return r.length>0?r.map(String).join(` · `):`#${n}`}function Ll(e){let t=[],n=Array.isArray(e.objects)?e.objects:[],r=Array.isArray(e.data)?e.data:[];if(n.length===0||r.length===0)return t;let i=Fl(n);return i.size===0||r.forEach((e,n)=>{if(!e||typeof e!=`object`)return;let r=typeof e.object==`string`?e.object:void 0;if(!r)return;let a=i.get(r);a&&(Array.isArray(e.records)?e.records:[]).forEach((i,o)=>{if(i&&typeof i==`object`)for(let s of a){let a=i[s.field];a!=null&&a!==``&&typeof a==`string`&&(s.states.has(a)||t.push({severity:`warning`,rule:Pl,where:`seed "${r}" (${Il(i,e.externalId,o)})`,path:`data[${n}].records[${o}].${s.field}`,message:`seeds '${s.field}=${a}', which the '${r}' state machine does not declare (known states: ${[...s.states].sort().join(`, `)}). Seed writes are exempt from the state_machine rule (#3433), so this is NOT rejected at write time \u2014 a typo lands silently.`,hint:`If '${a}' is a real state, add it to the state machine (as an initial state or a transition endpoint). If it is a typo, correct it to a declared state. The exemption lets a seed be born mid-lifecycle; it is not a licence to write an unknown state.`}))}})}),t}var Rl=`security-owd-unset`,zl=`security-owd-alias`,Bl=`security-external-wider-than-internal`,Vl=`security-wildcard-vama`,Hl=`security-anchor-high-privilege`,Ul=`security-role-word`,Wl=`security-book-audience-unknown-set`,Gl=`security-private-no-readscope`,Kl=`security-master-detail-ungranted`,ql=`security-fls-unqualified-key`,Jl=`security-fls-unknown-field`,Yl=`security-grant-expired-at-authoring`,Xl=`security-delegation-missing-reason`,Zl=`security-controlled-by-parent-no-relation`,Ql=`security-controlled-by-parent-ambiguous-relation`,$l=[`private`,`public_read`,`public_read_write`,`controlled_by_parent`],eu={read:`public_read`,read_write:`public_read_write`,full:`public_read_write`},tu={public:`public_read_write`},nu={...eu,...tu},ru={private:0,public_read:1,public_read_write:2};function iu(e){return e.sharingModel}function au(e){return eu[e]?`is a retired alias (ADR-0090 D4)`:`is not an OWD value and never was \u2014 ADR-0090 D4 retired 'read', 'read_write' and 'full', not this. '${e}' is legal on the neighbouring keys 'access' (its 'default') and 'publicSharing' (its 'allowedAudiences'), just not on this one`}function ou(e){return e.isSystem===!0||String(e.name??``).startsWith(`sys_`)}function su(e){return typeof e==`string`&&e.toLowerCase().split(/[^a-z0-9]+/).some(e=>e===`role`||e===`roles`)}function cu(e){return typeof e==`string`&&/\brole(s)?\b/i.test(e)}function lu(e){let t=e.reference;return typeof t==`string`&&t?t:void 0}function uu(e){for(let t of w(e.fields))if(t.type===`master_detail`)return{name:String(t.name??`?`),parent:lu(t)}}var du=[{label:`required master_detail`,pred:e=>e.type===`master_detail`&&!!e.required},{label:`any master_detail`,pred:e=>e.type===`master_detail`},{label:`required lookup`,pred:e=>e.type===`lookup`&&!!e.required}];function fu(e){let t=w(e.fields);for(let{label:e,pred:n}of du){let r=t.filter(e=>n(e)&&lu(e));if(r.length>0)return{tier:e,candidates:r.map(e=>({field:String(e.name??`?`),type:String(e.type),master:lu(e)}))}}}function pu(e){return fu(e)?.candidates[0]}function mu(e){return e.allowRead===!0||e.allowCreate===!0||e.allowEdit===!0||e.allowDelete===!0||e.viewAllRecords===!0||e.modifyAllRecords===!0}function hu(e,t){let n=[];if(!e||typeof e!=`object`)return n;let r=w(e.objects),i=w(e.permissions);for(let e=0;e<r.length;e++){let t=r[e];if(!t||typeof t!=`object`)continue;let i=typeof t.name==`string`?t.name:`(object ${e})`,a=`objects[${e}]`,o=iu(t),s=t.externalSharingModel;ou(t)||(o==null?n.push({severity:`error`,rule:Rl,where:`object "${i}"`,path:`${a}.sharingModel`,message:`custom object "${i}" declares no sharingModel (OWD). The runtime fails CLOSED to 'private' (ADR-0090 D1), but the baseline must be an authored decision, not an accident \u2014 this is the exact shape of the leave_request incident (objectui#2348).`,hint:`Declare sharingModel explicitly: 'private' (owner + shares; recommended default), 'public_read', 'public_read_write', or 'controlled_by_parent' (master-detail children).`}):typeof o==`string`&&nu[o]?n.push({severity:`error`,rule:zl,where:`object "${i}"`,path:`${a}.sharingModel`,message:`sharingModel '${o}' ${au(o)}. The runtime fails CLOSED to 'private' on unknown values, so this object is NOT ${o===`read`?`readable`:`writable`} org-wide.`,hint:`Replace with the canonical value: sharingModel: '${nu[o]}'.`}):typeof o==`string`&&!$l.includes(o)&&n.push({severity:`error`,rule:zl,where:`object "${i}"`,path:`${a}.sharingModel`,message:`sharingModel '${o}' is not a canonical OWD value; the runtime fails CLOSED to 'private'.`,hint:`Use one of: ${$l.join(`, `)}.`})),o===`controlled_by_parent`&&!pu(t)&&n.push({severity:`error`,rule:Zl,where:`object "${i}"`,path:`${a}.sharingModel`,message:`"${i}" declares sharingModel 'controlled_by_parent' but has no relation the platform can derive access from. ADR-0055 resolves the master through a required master_detail, then any master_detail, then a required lookup \u2014 each of which must also name a reference target \u2014 and this object matches none of the three. At runtime every read is DENIED and every write is refused with 422 INVALID_METADATA (#7474), so the object is unusable rather than merely locked down.`,hint:`Add the master relation this object is derived from, e.g. fields.parent: { type: 'master_detail', reference: '<master_object>', required: true }. If the object has no master, its baseline is its own decision — use sharingModel: 'private' (owner + shares), 'public_read', or 'public_read_write'.`});let c=o===`controlled_by_parent`?fu(t):void 0;if(c&&c.candidates.length>1){let e=c.candidates[0],t=c.candidates.map(e=>`"${e.field}" (${e.type} -> "${e.master}")`).join(`, `);n.push({severity:`error`,rule:Ql,where:`object "${i}"`,path:`${a}.fields`,message:`"${i}" declares sharingModel 'controlled_by_parent' and ${c.candidates.length} of its fields tie for the master relation: ${t}. ADR-0055 resolves the master through a required master_detail, then any master_detail, then a required lookup, and takes the FIRST match in the tier that wins \u2014 here the ${c.tier} tier \u2014 so which object this one derives its access from is decided by FIELD DECLARATION ORDER. Today "${e.field}" wins and every row's record-level access derives from "${e.master}"; reordering these fields moves that security boundary to another object, and the runtime reports nothing when it does.`,hint:`Leave exactly ONE candidate in the winning tier, so the master is authored rather than positional. Either promote the intended master into a higher tier — make it the object's only required master_detail ({ type: 'master_detail', reference: '<master_object>', required: true }) — or demote the others in this tier (drop required, or change the relation type). Precedence is required master_detail, then any master_detail, then a required lookup; only a tie inside the tier that WINS is ambiguous.`})}typeof s==`string`&&(nu[s]?n.push({severity:`error`,rule:zl,where:`object "${i}"`,path:`${a}.externalSharingModel`,message:`externalSharingModel '${s}' ${au(s)}.`,hint:`Replace with the canonical value: externalSharingModel: '${nu[s]}'.`}):typeof o==`string`&&s in ru&&o in ru&&ru[s]>ru[o]&&n.push({severity:`error`,rule:Bl,where:`object "${i}"`,path:`${a}.externalSharingModel`,message:`externalSharingModel '${s}' is WIDER than the internal sharingModel '${o}' \u2014 the external baseline must never exceed the internal one (ADR-0090 D11).`,hint:`Narrow externalSharingModel to '${o}' or below (ordering: private < public_read < public_read_write).`}))}let a=jt(e);for(let e=0;e<i.length;e++){let t=i[e];if(!t||typeof t!=`object`)continue;let r=typeof t.name==`string`?t.name:`(permission set ${e})`,o=`permissions[${e}]`,s=t.objects&&typeof t.objects==`object`?t.objects:{},c=t.fields&&typeof t.fields==`object`?t.fields:{};for(let e of Object.keys(c))e.includes(`.`)||n.push({severity:`error`,rule:ql,where:`permission set "${r}"`,path:`${o}.fields["${e}"]`,message:`field-permission key '${e}' is not object-qualified \u2014 the runtime matches FLS keys by '<object>.<field>' prefix, so a bare key is silently IGNORED and the declared masking never enforces.`,hint:`Qualify the key with its object, e.g. 'crm_opportunity.${e}': { readable: true, editable: false }.`});for(let e of Object.keys(c)){let t=e.indexOf(`.`);if(t<0)continue;let i=e.slice(0,t),s=e.slice(t+1);if(!a.has(i))continue;let c=a.get(i);if(!c||c.names.has(s)||c.injected.has(s))continue;let l=s.length===0,u=[...c.names].sort(),d=u.length<=12?u.join(`, `):`${u.slice(0,12).join(`, `)}, \u2026`,f=l?`field-permission key '${e}' names NO field \u2014 everything after the '${i}.' prefix is empty`:`field-permission key '${e}' is object-qualified but "${i}" declares no field '${s}'`,p=l?`A truncated key is what a half-finished edit leaves behind.`:`Unlike an unqualified key this one looks correct in review, and it is exactly what a field rename leaves behind.`;n.push({severity:`error`,rule:Jl,where:`permission set "${r}"`,path:`${o}.fields["${e}"]`,message:`${f}. The runtime resolves an FLS key by stripping the '${i}.' prefix and looking the remainder up as a column, so this key matches NOTHING: the masking it declares NEVER ENFORCES, and the field it was meant to cover stays as readable and as editable as the object-level grant leaves it \u2014 for every holder of this set. Nothing reports that at runtime. ${p}`,hint:`Point the key at a field "${i}" really declares (${d}), or delete the entry if the field is gone \u2014 an entry that cannot match is not protection. If the masking is still wanted, renaming the key is the fix; if the field was renamed, the mask has been off since that rename.`})}let l=s[`*`];if(l&&(l.viewAllRecords===!0||l.modifyAllRecords===!0)&&n.push({severity:`error`,rule:Vl,where:`permission set "${r}"`,path:`${o}.objects.*`,message:`'*' wildcard carrying View All / Modify All Data — a package-authored superuser. Only the platform's own admin set may combine the wildcard with VAMA (ADR-0066).`,hint:`Enumerate the objects this set really needs, or drop viewAllRecords/modifyAllRecords from the wildcard entry. App-level admins belong in an ordinary set the customer binds to a position of their choosing (ADR-0090 D9).`}),t.isDefault===!0){let e=_t(t,`everyone`);e&&n.push({severity:`error`,rule:Hl,where:`permission set "${r}"`,path:`${o}.isDefault`,message:`isDefault:true suggests binding this set to the 'everyone' audience anchor, but it carries ${e} \u2014 the runtime will refuse the binding (ADR-0090 D5/D9).`,hint:`Split the powerful bits into a separate set granted through ordinary positions, and keep the everyone-suggested set low-privilege.`})}}let o=new Set(i.map(e=>typeof e.name==`string`?e.name:void 0).filter(e=>!!e));for(let[t,r]of w(e.books).entries()){let e=r.audience;if(!e||typeof e!=`object`)continue;let i=e.permissionSet;typeof i==`string`&&i.length!==0&&(o.has(i)||n.push({severity:`warning`,rule:Wl,where:`book "${String(r.name??t)}"`,path:`books[${t}].audience.permissionSet`,message:`book audience references permission set "${i}", which this stack does not declare. The runtime fails closed \u2014 no holder means NO reader can open the book.`,hint:`Gate the book on one of this package's own permission sets (ADR-0090 D9, e.g. its admin set), or fix the typo. Ignore if the set is intentionally provided by another installed package.`}))}let s=new Set(r.filter(e=>e&&typeof e==`object`&&!ou(e)).filter(e=>{let t=iu(e);return t==null||t===`private`}).map(e=>String(e.name??``)));if(s.size>0)for(let e=0;e<i.length;e++){let t=i[e];if(!t||typeof t!=`object`)continue;let r=typeof t.name==`string`?t.name:`(permission set ${e})`,a=t.objects&&typeof t.objects==`object`?t.objects:{};for(let[t,i]of Object.entries(a)){if(!s.has(t))continue;let a=i??{};a.allowRead===!0&&a.readScope==null&&a.viewAllRecords!==!0&&n.push({severity:`info`,rule:Gl,where:`permission set "${r}"`,path:`permissions[${e}].objects.${t}.readScope`,message:`"${t}" is private (OWD) and this set grants allowRead without a readScope \u2014 holders see ONLY records they own (plus explicit shares).`,hint:`If that is intended (personal data), ignore this. Otherwise add readScope: 'own_and_reports' | 'unit' | 'unit_and_below' | 'org', or widen the object's sharingModel.`})}}if(i.length>0&&!i.some(e=>mu(e.objects?.[`*`]??{}))){let e=new Set;for(let t of i){let n=t.objects&&typeof t.objects==`object`?t.objects:{};for(let[t,r]of Object.entries(n))t!==`*`&&mu(r??{})&&e.add(t)}for(let t=0;t<r.length;t++){let i=r[t];if(!i||typeof i!=`object`||ou(i))continue;let a=typeof i.name==`string`?i.name:``;if(!a||e.has(a))continue;let o=uu(i);if(!o)continue;let s=o.parent?` \u2192 "${o.parent}"`:``;n.push({severity:`warning`,rule:Kl,where:`object "${a}"`,path:`objects[${t}].fields.${o.name}`,message:`detail object "${a}" (master_detail "${o.name}"${s}) has no object-level CRUD grant in any permission set. A master-detail child derives its RECORD-level access from the master (ADR-0055 controlled_by_parent), but object-level CRUD is a SEPARATE gate that is never derived \u2014 role-bound non-admin users are denied (403) before the parent-derived access is ever consulted (the silent "can't submit the subtable" trap).`,hint:`Grant "${a}" in at least one permission set that already grants its master${o.parent?` "${o.parent}"`:``} \u2014 e.g. permissions[i].objects.${a} = { allowRead: true, allowCreate: true, allowEdit: true }. If no role should ever touch it (a pure system/internal table), name it sys_* or set isSystem: true.`})}}let c=new Set([`sys_user_position`,`sys_user_permission_set`]),l=new Set([`sys_user_position`]),u=t?.nowMs??Date.now();for(let[t,r]of w(e.data).entries()){let e=typeof r.object==`string`?r.object:``;if(!c.has(e))continue;let i=Array.isArray(r.records)?r.records:[];for(let r=0;r<i.length;r++){let a=i[r]??{},o=`seed "${e}" record #${r}`,s=a.valid_until;if(s!=null&&s!==``){let e=typeof s==`number`?s<0xe8d4a51000?s*1e3:s:s instanceof Date?s.getTime():typeof s==`string`?Date.parse(s):NaN;(Number.isNaN(e)||e<=u)&&n.push({severity:`error`,rule:Yl,where:o,path:`data[${t}].records[${r}].valid_until`,message:Number.isNaN(e)?`valid_until ${JSON.stringify(s)} is not a parseable timestamp \u2014 the resolver fails closed (ADR-0091 D2), so this grant will NEVER be active.`:`valid_until ${JSON.stringify(s)} is already in the past \u2014 this grant is expired at authoring time and will never resolve (ADR-0091 D2 filters it fail-closed).`,hint:`Set valid_until to a future instant (ISO-8601 UTC), or drop the column for an unbounded grant. If the row is a historical record, it belongs in audit history, not seed data.`})}let c=a.delegated_from;if(l.has(e)&&c!=null&&c!==``){let e=a.reason;(typeof e!=`string`||e.trim().length===0)&&n.push({severity:`error`,rule:Xl,where:o,path:`data[${t}].records[${r}].reason`,message:`delegation row (delegated_from = ${JSON.stringify(c)}) has no reason. ADR-0091 D3 requires a mandatory reason on every delegation for the dual audit trail (granted_by = writer, delegated_from = authority source, reason = why).`,hint:`Add reason: 'vacation stand-in for 张三, 2026-08-01..15' (free text, required).`})}}}return n}function gu(e){let t=[];if(!e||typeof e!=`object`)return t;let n=w(e.objects),r=w(e.permissions),i=(e,n,r,i,a)=>{su(n)?t.push({severity:`error`,rule:Ul,where:i,path:a,message:`${e} name "${String(n)}" uses the reserved word "role" \u2014 the platform vocabulary is permission_set (capability), position (distribution), business_unit (hierarchy) (ADR-0090 D3).`,hint:`Rename using 'position' for distribution groups or a domain word (e.g. 'function', 'duty').`}):cu(r)&&t.push({severity:`error`,rule:Ul,where:i,path:`${a.replace(/\.name$/,``)}.label`,message:`${e} label "${String(r)}" uses the reserved word "role" (ADR-0090 D3).`,hint:`Relabel with 'Position' (distribution) or a domain word — admins must meet ONE vocabulary.`})};for(let e=0;e<n.length;e++){let t=n[e];if(!t||typeof t!=`object`||ou(t))continue;let r=typeof t.name==`string`?t.name:`(object ${e})`;i(`object`,t.name,t.label,`object "${r}"`,`objects[${e}].name`);for(let n of w(t.fields))i(`field`,n.name,n.label,`field "${r}.${String(n.name??`?`)}"`,`objects[${e}].fields.${String(n.name??`?`)}.name`);for(let[n,a]of w(t.actions).entries())i(`action`,a.name,a.label,`action "${r}.${String(a.name??`?`)}"`,`objects[${e}].actions[${n}].name`)}for(let e=0;e<r.length;e++){let t=r[e];t&&typeof t==`object`&&i(`permission set`,t.name,t.label,`permission set "${String(t.name??e)}"`,`permissions[${e}].name`)}for(let[t,n]of w(e.positions).entries())i(`position`,n.name,n.label,`position "${String(n.name??t)}"`,`positions[${t}].name`);for(let[t,n]of w(e.apps).entries())i(`app`,n.name,n.label,`app "${String(n.name??t)}"`,`apps[${t}].name`);for(let[t,n]of w(e.books).entries())i(`book`,n.name,n.label,`book "${String(n.name??t)}"`,`books[${t}].name`);return t}var _u=`org-axis-permission-inheritance`,vu=`org-axis-cross-org-bu-grant`,yu=`parent_organization_id`,bu=new Set([`business_unit`,`unit_and_subordinates`]);function xu(e){return typeof e==`string`?e:``}function Su(e){if(typeof e==`string`)return e;if(e&&typeof e==`object`){let t=e;if(typeof t.source==`string`)return t.source;if(t.ast!==void 0)return JSON.stringify(t.ast)??``}return``}function Cu(e){let t=e.tenancy;if(t&&typeof t==`object`&&t.enabled===!1)return!0;let n=e.systemFields;return!!(n&&typeof n==`object`&&n.tenant===!1)}var wu=`Remove the ${yu} reference. Cross-organization visibility comes from MEMBERSHIP: under the \`group\` tenancy posture the engine's Layer 0 wall is \`organization_id IN accessible_org_ids\`, so a user who should see several organizations is made a member of them (ADR-0105 D2). A Layer-1 policy cannot widen Layer 0 anyway, so this rule would not grant the access it appears to. For a hierarchy INSIDE one organization, use the business-unit tree (\`unit_and_subordinates\` sharing, or a depth scope anchored on \`sys_user_position\`).`;function Tu(e){let t=[],n=e??{};w(n.permissions).forEach((e,n)=>{w(e.rowLevelSecurity).forEach((r,i)=>{for(let a of[`using`,`check`])xu(r[a]).includes(yu)&&t.push({severity:`error`,rule:_u,where:`permission set "${xu(e.name)||n}" policy "${xu(r.name)||i}"`,path:`permissions[${n}].rowLevelSecurity[${i}].${a}`,message:`RLS ${a} reads \`${yu}\`, which builds a permission hierarchy along the organization axis. ADR-0105 D6 forbids it: the org tree is a REPORTING dimension only.`,hint:wu})})}),w(n.sharingRules).forEach((e,n)=>{let r=[{key:`condition`,text:Su(e.condition)},{key:`sharedWith`,text:JSON.stringify(e.sharedWith??``)??``}];for(let i of r)i.text.includes(yu)&&t.push({severity:`error`,rule:_u,where:`sharing rule "${xu(e.name)||n}"`,path:`sharingRules[${n}].${i.key}`,message:`Sharing rule ${i.key} reads \`${yu}\`, granting access by walking the organization tree. ADR-0105 D6 forbids permission inheritance along the org axis.`,hint:wu})});let r=new Set(w(n.objects).filter(e=>Cu(e)).map(e=>xu(e.name)).filter(Boolean));return w(n.sharingRules).forEach((e,n)=>{let i=xu(e.object);if(!i||!r.has(i))return;let a=e.sharedWith,o=xu(a?.type);if(!bu.has(o))return;let s=o===`unit_and_subordinates`?`a business unit AND every descendant unit`:`a business unit`;t.push({severity:`error`,rule:vu,where:`sharing rule "${xu(e.name)||n}" on object "${i}"`,path:`sharingRules[${n}].sharedWith`,message:`Sharing rule recipient \`${o}\` (${s}) targets "${i}", which opted out of tenancy (\`tenancy.enabled: false\`). Platform-global objects carry no organization column, so this grant spans EVERY organization \u2014 a cross-organization business-unit grant, which ADR-0105 D6 forbids (BU trees are org-internal).`,hint:"Either scope the object to organizations (drop `tenancy.enabled: false` so Layer 0 walls it), or share it to a `user` / `team` / `position` audience instead — those expand flat, with no business-unit tree to resolve. A platform-global catalog that everyone should read wants an OWD of `public_read`, not a BU grant."})}),t}var Eu=`sharing-rule-unlowerable-condition`,Du=`sharing-rule-runtime-variable-condition`,Ou=`sharing-rule-object-not-shareable`,ku=`sharing-rule-object-controlled-by-parent`;function Au(e){return typeof e==`string`?e:``}function ju(e){if(typeof e==`string`)return e.trim()?e:null;if(e&&typeof e==`object`){let t=e.source;if(typeof t==`string`&&t.trim())return{source:t}}return null}function Mu(e){let t=ju(e);return typeof t==`string`?t:Au(t?.source)}var Nu="The lowerable subset is: `==` `!=` `>` `<` `>=` `<=`, `in`, `&&` `||` `!`, `== null` / `!= null`, and the string methods `startsWith` / `endsWith` / `contains` — over SINGLE-column `record.<field>` paths (ADR-0058 D2).";function Pu(e){let t=e.sharingModel;return t===`private`?`private`:t===`public_read`?`read`:t===`public_read_write`||t===`controlled_by_parent`||t==null&&(e.isSystem===!0||Au(e.name).startsWith(`sys_`))?`public`:`private`}function Fu(e){for(let t of w(e.fields))if(t.type===`master_detail`){let e=t.reference;if(typeof e==`string`&&e)return e}}function Iu(e,t,n){let r=Au(e.object);if(!r)return[];let i=n.get(r);if(!i)return[];let a=Au(e.name)||String(t),o=`sharing rule "${a}" on object "${r}"`,s=`sharingRules[${t}].object`,c=i.sharingModel;if(c===`controlled_by_parent`){let e=Fu(i);return[{severity:`error`,rule:ku,where:o,path:s,message:`Sharing rule "${a}" is anchored on object "${r}", which declares sharingModel 'controlled_by_parent'. A detail record has no record-level access of its own \u2014 its visibility is DERIVED from its master (ADR-0055), so it holds no shares to widen. \`SharingService.assertNotInertGrant\` refuses the grant with SHARING_NOT_ENABLED ("'${r}' is controlled by its parent (master-detail); share the master record instead"), so the rule's boot backfill fails, no \`sys_record_share\` row is ever written, and the recipients this rule names get whatever the MASTER grants them \u2014 which may be nothing. The grant is declared and does not exist.`,hint:`Move the rule onto the MASTER object`+(e?` \u2014 "${r}" derives from "${e}" through its master_detail field, so share "${e}" and the detail rows follow`:`, and share that instead; the detail rows follow`)+`. If "${r}" is meant to carry a record-level baseline of its own, that is a different decision: change its sharingModel to 'private' (owner + shares) or 'public_read', and this rule becomes enforceable where it stands.`}]}return Pu(i)===`public`?[{severity:`error`,rule:Ou,where:o,path:s,message:`Sharing rule "${a}" is anchored on object "${r}", which ${c===`public_read_write`?`declares sharingModel 'public_read_write'`:"declares no sharingModel and is a system object (`isSystem: true` or a `sys_` name), which ADR-0090 D1 resolves to public"}. Its effective sharing model is therefore \`public\`, and sharing only ever WIDENS an OWD baseline \u2014 on the widest baseline there is nothing left to widen. \`SharingService.assertNotInertGrant\` refuses the grant with SHARING_NOT_ENABLED ("'${r}' is not under record-sharing enforcement"), so the rule's boot backfill fails and no \`sys_record_share\` row is ever written. Measured: \`buildReadFilter\` returns \`null\` for this object, i.e. NO record-level filter at all \u2014 every principal already reads every row, so this rule advertises a restriction that does not exist.`,hint:`Decide which half is wrong. If the ACCESS is right \u2014 everyone should read and write these records \u2014 the rule is dead metadata: delete it (ADR-0049 enforce-or-remove). If the RULE is right \u2014 only the named audience should reach these records \u2014 then "${r}"'s OWD is the defect: set sharingModel: 'private' (owner + shares) or 'public_read', and this rule starts enforcing. Do NOT re-home the rule onto another public object; that moves the inertness instead of removing it.`}]:[]}function Lu(e){let t=[],n=e??{},r=new Map;for(let e of w(n.objects)){let t=Au(e.name);t&&r.set(t,e)}return w(n.sharingRules).forEach((e,n)=>{Iu(e,n,r).forEach(e=>t.push(e));let i=ju(e.condition);if(i===null)return;let a=Ue(i,{variables:{}});if(a.ok||a.reason===`parse-error`)return;let o=Au(e.name)||String(n),s=Au(e.object),c=`sharing rule "${o}"${s?` on object "${s}"`:``}`,l=`sharingRules[${n}].condition`,u=Mu(e.condition);if(a.reason===`unresolved-variable`){t.push({severity:`error`,rule:Du,where:c,path:l,message:`Sharing-rule condition \`${u}\` reads a runtime variable (${a.detail}), so \`bootstrapDeclaredSharingRules\` SKIPS the rule at boot: it is never written to \`sys_sharing_rule\`, no \`sys_record_share\` grant is ever materialised, and the only signal is one WARN line in the boot log. The rule is declared and grants nothing (ADR-0049: an unlowerable condition is never seeded as a permissive match-all).`,hint:'A criteria sharing rule is MATERIALISED: the seeder compiles ONE static `criteria_json` per rule and the evaluator writes `sys_record_share` rows from it, so there is no "current user" for the condition to read. WHICH mechanism replaces it depends on the anchor object\'s `sharingModel`, because the security layers are AND-composed (`getReadFilter` = RLS AND controlled-by-parent AND sharing) and an AND term can only REMOVE rows — it can never add one back. On `public_read` / `public_read_write` the sharing layer imposes nothing on reads (`buildReadFilter` constrains `private` only), so an RLS policy on a permission set (`rowLevelSecurity[].using`, where `current_user.*` IS resolved) is the right mechanism: it NARROWS an open baseline, the direction AND can express. On `private` — including a CUSTOM object that declares no `sharingModel`, which resolves to `private` (ADR-0090 D1) — that same policy CANNOT work: the sharing layer has already withheld the row, and AND-ing an RLS predicate onto it can only withhold more, so the policy lints clean, passes every gate and grants nothing. The two doors that widen a `private` object for a non-admin principal both key on WHO OWNS the row or on an explicit share row, never on a property of the record: the ADR-0057 D1 depth scopes (`readScope` / `writeScope` on the object permission — `own` | `own_and_reports` | `unit` | `unit_and_below` | `org`), which widen the owner-match to `owner_id IN (…)`; and a `sys_record_share` row, which on this path only a criteria sharing rule writes — i.e. THIS rule. So keep this rule for the part of the predicate that is a property of the RECORD (e.g. `record.stage == \'closed_won\'`) and name the audience through `sharedWith`. If the audience is genuinely record-relative ("the owner\'s manager", "this record\'s approver"), no mechanism expresses it today — `sharedWith` recipients resolve tenant-wide, so reaching for `position` shares every matched row with EVERY holder of that position (the skip-level, the manager two teams over): an over-broad grant, not the narrower one you meant. That is a known gap in the platform, not something a different spelling of this rule can close — leave the grant unauthored rather than widening it, and ask for record-relative sharing recipients.'});return}t.push({severity:`error`,rule:Eu,where:c,path:l,message:`Sharing-rule condition \`${u}\` is outside the pushdown subset the runtime can compile (${a.detail}), so \`bootstrapDeclaredSharingRules\` SKIPS the rule at boot: it is never written to \`sys_sharing_rule\`, no \`sys_record_share\` grant is ever materialised, and the only signal is one WARN line in the boot log. The rule is declared and grants nothing (ADR-0049: an unlowerable condition is never seeded as a permissive match-all).`,hint:`Rewrite the predicate inside the lowerable subset. `+Nu+" Two traps in particular: (1) `has(record.x)` is correct in an object VALIDATION rule, which is INTERPRETED, and wrong here, where the condition is COMPILED — write the null test as `record.x != null`; (2) a related-record path (`record.account.region`) is a join, which the compiler refuses by design (ADR-0055) — denormalise the value onto this object (a formula/rollup field) and test that column, or share the related object instead."})}),t}var Ru=`rls-predicate-unenforceable`,zu=`rls-predicate-unparseable`,Bu=`rls-predicate-over-budget`;function Vu(e){return typeof e==`string`?e:``}var Hu="The lowerable subset is: `==` `!=` `>` `<` `>=` `<=`, `in`, `&&` `||` `!`, `== null` / `!= null`, and the string methods `startsWith` / `endsWith` / `contains` — over SINGLE-column field paths (ADR-0058 D2), compared against a literal or a `current_user.*` value.";function Uu(e){let t=Te(e);return!t.ok&&t.kind===`bounds`?t.overrun:null}function Wu(e){return e.length>200?`${e.slice(0,197)}...`:e}function Gu(e){let t='so `RLSCompiler` DROPS the policy at request time (one WARN line — "has an uncompilable predicate … and was DROPPED (no enforcement)" — is the only signal, and nothing reports it at authoring time). ';return e===`using`?t+"When it is the only applicable policy for that object and operation, `compileFilter` returns the `RLS_DENY_FILTER` sentinel instead, which is AND-ed onto the where clause: every select / update / delete on the object matches ZERO rows. When other policies also apply, this one just vanishes from the OR and grants none of the access it appears to.":t+"On the ADR-0058 D4 write path that leaves the post-image `check` as the `RLS_DENY_FILTER` sentinel, which no record can satisfy: every insert / update the policy governs fails with `PermissionDeniedError`. The policy reads as a write rule and behaves as a blanket refusal."}function Ku(e){let t=[];return w((e??{}).permissions).forEach((e,n)=>{w(e.rowLevelSecurity).forEach((r,i)=>{for(let a of[`using`,`check`]){let o=Vu(r[a]);if(!o.trim()||Ke(o))continue;let s=dt(o),c=Ze(s),l=c.ok?``:c.detail,u=!c.ok&&c.reason===`parse-error`,d=u?Uu(s):null,f=Vu(e.name)||String(n),p=Vu(r.name)||String(i),m=Vu(r.object),h=`permission set "${f}" policy "${p}"`+(m?` on object "${m}"`:``),g=`permissions[${n}].rowLevelSecurity[${i}].${a}`;if(d){let e=d.limit??`an unnamed platform CEL bound`,n=d.limitValue===null?``:` (platform limit ${d.limitValue})`,r=d.measured===null?``:`, this predicate measures ${d.measured}`;t.push({severity:`error`,rule:Bu,where:h,path:g,message:`RLS ${a} \`${Wu(o)}\` is syntactically valid, lowerable CEL but overruns the platform parse bound ${e}${n}${r} (${d.summary}), `+Gu(a),hint:`There is no syntax or dialect error to correct here \u2014 the predicate is well-formed CEL and is simply too large for ${e}${n}, so the fix is to make it smaller or to move the work off the predicate. (1) Collapse a long \`field == a || field == b || \u2026\` chain into a single \`field in [a, b, \u2026]\`, which is far fewer AST nodes (\`maxListElements\` is 64, so a very large set needs option 2). (2) Pre-resolve the set into a membership key the runtime exposes and test \`field in current_user.<key>\` (ADR-0105 D11) \u2014 one comparison whatever the set size. (3) Denormalise a repeated sub-expression onto this object as a formula/rollup field and test that single column. (4) Split a TOP-LEVEL \`||\` across several \`rowLevelSecurity\` policies: applicable policies are OR-ed, so that is equivalent \u2014 but never split a top-level \`&&\` this way, which would WIDEN access rather than preserve it. Logic genuinely this large is not a row filter: move it to a hook or action body (\`ScriptBody { language: 'js' }\`, the L2 sandboxed surface).`});continue}if(u){t.push({severity:`error`,rule:zu,where:h,path:g,message:`RLS ${a} \`${o}\` does not parse as CEL even after the legacy SQL bridge (\`=\` \u2192 \`==\`, \`IN\` \u2192 \`in\`) has been applied (${l}), `+Gu(a),hint:"Author the predicate in canonical CEL (ADR-0058 D1). The bridge covers only the historic SQL subset — a bare `=` and `IN` — so everything else must already be CEL: combine with `&&` / `||` rather than SQL `AND` / `OR`, negate with `!`, and use `startsWith` / `endsWith` / `contains` rather than `LIKE`. A subquery has no CEL spelling at all: RLS cannot join (ADR-0055), so pre-resolve the set into a membership key the runtime exposes (`field in current_user.<key>`, ADR-0105 D11) or denormalise the value onto this object."});continue}t.push({severity:`error`,rule:Ru,where:h,path:g,message:`RLS ${a} \`${o}\` is outside the pushdown subset the runtime can compile (${l}), `+Gu(a),hint:`Rewrite the predicate inside the lowerable subset. `+Hu+" Three traps in particular: (1) a function call — `size(record.tags) > 0`, `has(record.x)` — is correct in an object VALIDATION rule, which is INTERPRETED, and wrong here, where the predicate is COMPILED to a filter; write the null test as `field != null`. (2) A related-record path (`record.account.region`) is a join, which the compiler refuses by design (ADR-0055) — denormalise the value onto this object (a formula/rollup field) and test that column. (3) Arithmetic on a column (`amount * 2 > 100`) never lowers — precompute it into a field, or compare the column against the literal directly."})}})}),t}var qu=`dashboard-action-target-undefined`,Ju=`dashboard-action-route-unresolved`;function I(e){return typeof e==`string`&&e.length>0?e:void 0}var Yu={app:`apps`,apps:`apps`,object:`objects`,objects:`objects`,report:`reports`,reports:`reports`,dashboard:`dashboards`,dashboards:`dashboards`,page:`pages`,pages:`pages`,view:`views`,views:`views`};function Xu(e){return I(e.name)??I(e.id)??I(e.object)??I(e.list?.data&&e.list.data.object)??I(e.form?.data&&e.form.data.object)}function Zu(e){let t=new Set,n=new Set,r=new Set,i=new Set,a=new Set,o=new Set,s=new Set,c=(e,t,n)=>{for(let r of w(e)){if(!r||typeof r!=`object`)continue;let e=n(r);e&&t.add(e)}};c(e.actions,t,e=>I(e.name)),c(e.apps,n,e=>I(e.name));for(let n of w(e.objects)){if(!n||typeof n!=`object`)continue;let e=I(n.name);e&&r.add(e),c(n.actions,t,e=>I(e.name))}c(e.reports,i,e=>I(e.name)),c(e.dashboards,a,e=>I(e.name)),c(e.pages,o,e=>I(e.name)),c(e.views,s,Xu);for(let e of r)s.add(e);return{actions:t,apps:n,objects:r,reports:i,dashboards:a,pages:o,views:s}}function Qu(e,t,n){return e===`modal`?n.pages.has(t):n.actions.has(t)}function $u(e,t){if(/^[a-z][a-z0-9+.-]*:\/\//i.test(e)||e.startsWith(`//`)||e.includes("${")||!e.startsWith(`/`))return[];let n=e.split(/[?#]/,1)[0].split(`/`).filter(Boolean),r=[];for(let e=0;e<n.length-1;e++){let i=Yu[n[e]];if(!i)continue;let a=n[e+1];t[i].has(a)||r.push({collection:n[e],name:a})}return r}function ed(e){let t=[];if(!e||typeof e!=`object`)return t;let n=w(e.dashboards);if(n.length===0)return t;let r=Zu(e),i=(e,n,i)=>{let a=I(e.actionUrl);if(!a||a.includes("${"))return;let o=I(e.actionType)??`url`;if(o===`script`||o===`modal`){if(Qu(o,a,r))return;t.push({severity:`error`,rule:qu,where:n,path:i,message:o===`modal`?`modal action target "${a}" names no declared page \u2014 a modal target names a PAGE, only (objectstack#6739). The button renders but the runtime refuses the dispatch when clicked \u2014 a dangling reference (ADR-0049: a declared reference must resolve).`:`script action target "${a}" resolves to no defined action. The button renders but does nothing when clicked \u2014 a dangling reference the runtime cannot dispatch (ADR-0049: a declared reference must resolve).`,hint:o===`modal`?`Point actionUrl at a declared page (stack.pages), or use actionType: 'form' with an "<object>.<view>" form-view target to open an object's form, or remove the button.`:`Define a script action named "${a}" (stack.actions or the object's actions) with an inline body or a registered handler, or remove the button.`});return}if(o===`url`){let e=$u(a,r);for(let r of e)t.push({severity:`warning`,rule:Ju,where:n,path:i,message:`url action target "${a}" points at ${r.collection}/${r.name}, but no ${r.collection.replace(/s$/,``)} named "${r.name}" is registered in this stack \u2014 the button likely navigates to a dead route.`,hint:`Check the path for a typo, define the referenced ${r.collection.replace(/s$/,``)}, or ignore this if the route is served by another installed package or a host/console route.`});return}};for(let e=0;e<n.length;e++){let t=n[e];if(!t||typeof t!=`object`)continue;let r=I(t.name)??`(dashboard ${e})`,a=`dashboards[${e}]`,o=w(t.header?.actions);for(let e=0;e<o.length;e++){let t=o[e];t&&typeof t==`object`&&i(t,`dashboard "${r}" \xB7 header action "${I(t.label)??I(t.actionUrl)??`#${e}`}"`,`${a}.header.actions[${e}].actionUrl`)}}return t}var td=`filter-token-unknown`,nd=he.join(`}, {`),rd=[{key:`dashboards`,kind:`dashboard`},{key:`objects`,kind:`object`},{key:`views`,kind:`view`},{key:`reports`,kind:`report`},{key:`datasets`,kind:`dataset`},{key:`pages`,kind:`page`},{key:`apps`,kind:`app`}];function id(e,t,n,r,i){if(e!=null){if(typeof e==`string`){let i=xe(e);if(i?.kind===`unknown`){let a=i.suggestion;r.push({severity:`error`,rule:td,where:n,path:t,message:`Filter value "${e}" is not a resolvable placeholder. It is sent to the data engine as a literal string, matches no record, and the surface renders empty.`,hint:a?`Did you mean "{${a}}"? Context tokens are {${nd}}; time-based values use date macros such as {today} or {30_days_ago}.`:`Resolvable placeholders are the context tokens {${nd}} and the date macros (e.g. {today}, {week_start}, {30_days_ago}). To filter on a literal value that happens to look like a placeholder, this is not supported \u2014 rename the value.`})}return}if(typeof e==`object`&&!i.has(e)){if(i.add(e),Array.isArray(e)){e.forEach((e,a)=>id(e,`${t}[${a}]`,n,r,i));return}for(let[a,o]of Object.entries(e))id(o,`${t}.${a}`,n,r,i)}}}function ad(e){if(!e||typeof e!=`object`)return[];let t=[];return Ht(e,rd,({value:e,path:n,where:r})=>{id(e,n,r,t,new Set)}),t}var od=/^(NOW|TODAY)\s*\(\s*\)\s*(?:([+\-])\s*(\S+))?$/,sd=/^[A-Za-z_$][\w$]*(?:\.(?:[A-Za-z_$][\w$]*|\d+))*$/,cd=/^[\w\s+\-*/%().,?:<>=!&|"'$]+$/,ld=/([A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*)/g,ud=/^\s*\(/,dd=new Set([`true`,`false`,`null`,`undefined`]),fd=[`NOW`,`TODAY`],pd=[`round`,`floor`,`ceil`,`abs`,`min`,`max`],md=new Set(pd);function hd(e){let t=e.trim();if(!t)return{kind:`unresolvable-shape`};let n=od.exec(t);if(n)return{kind:`date-function`,name:n[1]};if(t.startsWith(`$User.`))return{kind:`user-context`};if(sd.test(t))return{kind:`variable-path`,head:t.split(`.`)[0]};if(!cd.test(t))return{kind:`unresolvable-shape`};for(let e of t.matchAll(ld)){let n=e[0];if(dd.has(n))continue;let r=t.slice((e.index??0)+n.length);if(ud.test(r)&&!md.has(n))return{kind:`unknown-function`,name:n}}return{kind:`unresolvable-shape`}}var gd=`flow-filter-token-unknown`,_d=[{key:`flows`,kind:`flow`}];function vd(e){if(fd.includes(e))return`${e}() is supported only as the whole token, with an optional \xB1 N day offset \u2014 write {${e}() + 7}.`;let t=(e.includes(`.`)?e.slice(e.lastIndexOf(`.`)+1):e).toLowerCase(),n=pd.includes(t)?t:Ie(t,pd),r=n?` Did you mean '${n}'?${e.includes(`.`)?` Method/namespace call syntax is not supported — write the bare form.`:``}`:``;return`Flow filter values resolve in two vocabularies: the flow template dialect \u2014 {NOW()} / {TODAY()} with an optional \xB1 N day offset, {$User.Id}, {record.<field>}, and the value functions ${pd.join(`, `)} \u2014 and, for a token the evaluator does not resolve, the filter placeholders ({current_user_id}, {today}, {30_days_ago}).${r}`}function yd(e,t,n,r,i){if(e!=null){if(typeof e==`string`){let i=xe(e);if(i?.kind!==`unknown`)return;let a=hd(i.token);if(a.kind!==`unknown-function`)return;r.push({severity:`error`,rule:gd,where:n,path:t,message:`Filter value "${e}" calls '${a.name}', which is not a function in the flow template dialect and is not a filter placeholder either. The node does not query with an unresolved condition \u2014 the template evaluator raises a guard refusal, so this node cannot run at all.`,hint:vd(a.name)});return}if(typeof e==`object`&&!i.has(e)){if(i.add(e),Array.isArray(e)){e.forEach((e,a)=>yd(e,`${t}[${a}]`,n,r,i));return}for(let[a,o]of Object.entries(e))yd(o,`${t}.${a}`,n,r,i)}}}function bd(e){if(!e||typeof e!=`object`)return[];let t=[];return Ht(e,_d,({value:e,path:n,where:r})=>{yd(e,n,r,t,new Set)}),t}var xd=`filter-preset-comparand`,Sd=[{key:`dashboards`,kind:`dashboard`},{key:`objects`,kind:`object`},{key:`views`,kind:`view`},{key:`reports`,kind:`report`},{key:`datasets`,kind:`dataset`},{key:`pages`,kind:`page`},{key:`apps`,kind:`app`},{key:`flows`,kind:`flow`}],Cd=new Set([`$gt`,`$gte`,`$lt`,`$lte`]),wd=new Set([`>`,`>=`,`<`,`<=`]),Td=new Set([`greater_than`,`greater_than_or_equal`,`less_than`,`less_than_or_equal`,`before`,`after`]),Ed=new Set([`$eq`,`$ne`]),Dd=new Set([`$in`,`$nin`]),Od=new Set([`=`,`!=`]),kd=new Set([`in`,`nin`]),Ad=new Set([`equals`,`not_equals`]),jd=new Set([`in`,`not_in`]),Md=new Set([`date`,`datetime`]),Nd=32;function Pd(e){return!!e&&typeof e==`object`&&!Array.isArray(e)&&!(e instanceof Date)}function Fd(e){return typeof e==`string`&&e.length>0?e:void 0}function Id(e){let t=Fd(e);return t&&!t.includes(`{`)?t:void 0}function L(e,t,n,r){return{severity:`error`,rule:xd,where:e,path:t,message:f(n,r),hint:`Presets belong to the dashboard date-filter bar (dateRange.defaultRange, a date global filter's defaultValue). In a filter comparand, write the {date-macro} window the message names, or an ISO date.`}}var Ld=()=>!1;function Rd(e,t){return t?n=>{let r=Mt(e,t,n);if(!r||r.kind!==`ok`||r.injected)return!1;let i=r.meta?.type;return typeof i==`string`&&Md.has(i)}:Ld}function zd(e){let t=[];for(let n of e.split(`.`)){let e=/^([^[\]]+)((?:\[\d+\])*)$/.exec(n);if(!e)return null;t.push(e[1]);for(let n of e[2].match(/\d+/g)??[])t.push(Number(n))}return t}function Bd(e,t){let n=zd(t);if(!n||n.length<3)return null;let[r,i,...a]=n;if(typeof r!=`string`||typeof i!=`number`)return null;let o=w(e[r])[i];if(!o)return null;let s=[{key:r,node:o}],c=o,l=r;for(let e of a.slice(0,-1))if(typeof e==`string`&&(l=e),c=Array.isArray(c)||Pd(c)?c[e]:void 0,Pd(c))s.push({key:l,node:c});else if(!Array.isArray(c))break;return{collection:r,chain:s}}var Vd=`publicPicker`;function Hd(e,t,n,r){let i=Bd(e,t);if(i)return Ud(i.collection,i.chain,i.chain.length-1,n,r)}function Ud(e,t,n,r,i){for(let a=n;a>=0;a--){let{key:n,node:o}=t[a];if(n===Vd){let n=Id(o.object);if(n)return n;let s=Fd(t[a-1]?.node.field);if(!s)return;let c=Ud(e,t,a-2,r,i);if(!c)return;let l=Mt(i,c,s);return l?.kind===`ok`?Fd(l.meta?.reference):void 0}let s=Id(o.object)??Id(o.objectName);if(s)return s;let c=Fd(o.dataset);if(c){let e=r.get(c);return e?Id(e.object):void 0}if(Pd(o.data)){let e=o.data.provider;if(e!==void 0&&e!==`object`)return;let t=Id(o.data.object);if(t)return t}if(Pd(o.config)){let e=Id(o.config.objectName)??Id(o.config.object);if(e)return e}if(Pd(o.dataSource)){let e=Id(o.dataSource.object);if(e)return e}if(Pd(o.properties)){let e=Id(o.properties.object)??Id(o.properties.objectName);if(e)return e}}if(e===`objects`)return Fd(t[0].node.name)}function Wd(e,t,n,r,i,a,o){if(!(i>Nd))for(let[s,c]of Object.entries(e)){let e=`${t}.${s}`;if(s===`$and`||s===`$or`){Array.isArray(c)&&c.forEach((t,s)=>{Pd(t)&&Wd(t,`${e}[${s}]`,n,r,i+1,a,o)});continue}if(s===`$not`){Pd(c)&&Wd(c,e,n,r,i+1,a,o);continue}if(s.startsWith(`$`))continue;let l=o?`${o}.${s}`:s;if(!Pd(c)){S(c)&&a(l)&&r.push(L(n,e,c,`$eq`));continue}if(!Object.keys(c).some(e=>e.startsWith(`$`))){Wd(c,e,n,r,i+1,a,l);continue}for(let[t,i]of Object.entries(c)){if(Cd.has(t)&&S(i)){r.push(L(n,`${e}.${t}`,i,t));continue}if(t===`$between`&&Array.isArray(i)){i.forEach((i,a)=>{S(i)&&r.push(L(n,`${e}.${t}[${a}]`,i,t))});continue}if(Ed.has(t)&&S(i)&&a(l)){r.push(L(n,`${e}.${t}`,i,t));continue}Dd.has(t)&&Array.isArray(i)&&a(l)&&i.forEach((i,a)=>{S(i)&&r.push(L(n,`${e}.${t}[${a}]`,i,t))})}}}function Gd(e,t,n,r,i){let o=a(e.operator);if(typeof o!=`string`)return;let s=e.value;if(Td.has(o)&&S(s)){r.push(L(n,`${t}.value`,s,o));return}if(o===`between`&&Array.isArray(s)){s.forEach((e,i)=>{S(e)&&r.push(L(n,`${t}.value[${i}]`,e,o))});return}let c=Fd(e.field);if(c&&i(c)){if(Ad.has(o)&&S(s)){r.push(L(n,`${t}.value`,s,o));return}jd.has(o)&&Array.isArray(s)&&s.forEach((e,i)=>{S(e)&&r.push(L(n,`${t}.value[${i}]`,e,o))})}}function Kd(e,t,n,r,i){let a=e[1];if(typeof a!=`string`)return;let o=et(a),s=e[2];if(wd.has(o)&&S(s)){r.push(L(n,`${t}[2]`,s,a));return}if(o===`between`&&Array.isArray(s)){s.forEach((e,i)=>{S(e)&&r.push(L(n,`${t}[2][${i}]`,e,a))});return}let c=Fd(e[0]);if(c&&i(c)){if(Od.has(o)&&S(s)){r.push(L(n,`${t}[2]`,s,a));return}kd.has(o)&&Array.isArray(s)&&s.forEach((e,i)=>{S(e)&&r.push(L(n,`${t}[2][${i}]`,e,a))})}}function qd(e,t,n,r,i,a){if(!(i>Nd)){if(Array.isArray(e)){if(typeof e[0]==`string`&&typeof e[1]==`string`&&![`and`,`or`].includes(e[0].toLowerCase())&&h.has(e[1].toLowerCase())){Kd(e,t,n,r,a);return}e.forEach((e,o)=>{typeof e!=`string`&&qd(e,`${t}[${o}]`,n,r,i+1,a)});return}if(Pd(e)){if(typeof e.field==`string`&&typeof e.operator==`string`){Gd(e,t,n,r,a);return}Wd(e,t,n,r,i,a,``)}}}function Jd(e){if(!e||typeof e!=`object`)return[];let t=[],n=jt(e),r=new Map;for(let t of w(e.datasets)){let e=Fd(t.name);e&&r.set(e,t)}return Ht(e,Sd,({value:i,path:a,where:o})=>{let s=Rd(n,Hd(e,a,r,n));qd(i,a,o,t,0,s)}),t}var Yd=`filter-empty-combinator`,Xd=`filter-empty-node`,Zd=[{key:`dashboards`,kind:`dashboard`},{key:`objects`,kind:`object`},{key:`views`,kind:`view`},{key:`reports`,kind:`report`},{key:`datasets`,kind:`dataset`},{key:`pages`,kind:`page`},{key:`apps`,kind:`app`},{key:`flows`,kind:`flow`}];function Qd(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}var $d={$and:we({$and:[]}),$or:we({$or:[]}),$not:we({$not:{}}),node:we({}),orWithEmptyBranch:we({$or:[{status:`open`},{}]})};function ef(e){return e===`true`?`matches EVERY row`:e===`false`?`matches NO row`:`carries a real predicate`}var tf="If you really do want a predicate that selects nothing, `{ <field>: { $in: [] } }` is the declared spelling for it (an empty `$in` list matches nothing, on every backend) — it says so where an empty combinator only implies it.",nf='To express "no filter", DELETE the key — an absent `filter` and a filter that reduces to TRUE run identically, and only the absent key says so to the next reader (and to the next AI author that copies this metadata).';function rf(e,t,n){let r=e===`$not`?"`$not: {}`":`\`${e}: []\``,i=e===`$and`?`\`$and: []\` is a conjunction of ZERO conditions. Under the #5322 identity ruling it ${ef($d.$and)} \u2014 the key is authored, and it constrains nothing, so this surface reads as filtered and is not.`:e===`$or`?`\`$or: []\` is a disjunction of ZERO branches. Under the #5322 identity ruling it ${ef($d.$or)}: this surface renders permanently empty, and on a read scope it hides every row (fail-closed by design \u2014 #5134).`:`\`$not: {}\` negates an EMPTY node. An empty node is TRUE and NOT TRUE is FALSE, so it ${ef($d.$not)} \u2014 the opposite of the "no filter" an empty operand looks like.`,a=e===`$and`?`${nf} To express a constraint, put the conditions in the array. ${tf}`:e===`$or`?`If you meant "no filter", this is its OPPOSITE: emptying the array does not relax the filter, it closes it. ${nf} If you meant to offer alternatives, put the branches in the array. ${tf}`:`Put the condition you are negating inside \`$not\` (\`{ $not: { status: 'closed' } }\`). ${nf} ${tf}`;n.out.push({severity:`error`,rule:Yd,where:n.where,path:t,message:`${i} A literal ${r} is not an authoring surface (#5330).`,hint:`${a} A PROGRAMMATIC producer that loops to zero operands keeps the runtime identity unchanged \u2014 this rule judges only what is written in the metadata.`})}function af(e,t,n){if(e===`root`){n.out.push({severity:`error`,rule:Xd,where:n.where,path:t,message:`An EMPTY filter node (\`{}\`) is authored here. Under the #5322 identity ruling an empty node is TRUE \u2014 it ${ef($d.node)}, exactly as if the key were absent \u2014 so a filter is declared and enforces nothing.`,hint:`${nf} If you meant to constrain something, write the condition into the node. ${tf}`});return}if(e===`or-branch`){n.out.push({severity:`error`,rule:Xd,where:n.where,path:t,message:`An EMPTY branch (\`{}\`) of a \`$or\`. An empty node is TRUE, and one TRUE disjunct ABSORBS the whole disjunction (\`{ $or: [{ status: 'open' }, {}] }\` ${ef($d.orWithEmptyBranch)}), so every branch you wrote beside it is dead.`,hint:"Delete the empty branch — the `$or` then means what it looks like. If it was meant to carry a condition, write it. (A compiler that DROPPED the empty branch instead would silently NARROW the scope to the surviving branches, which is why the runtime absorbs rather than filters — #5297.)"});return}n.out.push({severity:`error`,rule:Xd,where:n.where,path:t,message:"An EMPTY branch (`{}`) of a `$and`. An empty node is TRUE — the AND identity — so the branch contributes no condition and the conjunction means whatever its other branches mean.",hint:`Delete the empty branch, or write the condition it was meant to carry. A branch that constrains nothing is indistinguishable from one whose condition was lost in an edit.`})}function of(e,t,n){for(let[r,i]of Object.entries(e)){if(r===`$and`||r===`$or`){if(!Array.isArray(i))continue;if(i.length===0){rf(r,`${t}.${r}`,n);continue}i.forEach((e,i)=>{sf(e,`${t}.${r}[${i}]`,r===`$and`?`and-branch`:`or-branch`,n)});continue}if(r===`$not`){if(!Qd(i))continue;if(Object.keys(i).length===0){rf(`$not`,`${t}.$not`,n);continue}of(i,`${t}.$not`,n);continue}}}function sf(e,t,n,r){if(Qd(e)){if(Object.keys(e).length===0){af(n,t,r);return}of(e,t,r)}}function cf(e){if(!e||typeof e!=`object`)return[];let t=[];return Ht(e,Zd,({value:e,path:n,where:r})=>{sf(e,n,`root`,{where:r,out:t})}),t}var lf=[...p],uf=`object-reference-unknown`,df=`object-reference-unregistered-platform`;function R(e){return typeof e==`string`&&e.length>0?e:void 0}function ff(e){if(e.includes("${"))return!0;let t=e.indexOf(`{`);return t!==-1&&e.indexOf(`}`,t+2)!==-1}function pf(e){let t=[];if(!e||typeof e!=`object`)return t;let n=w(e.objects),r=new Set;for(let e of n){let t=R(e.name);t&&r.add(t)}let i=(e,n,i,a,o)=>{let s=R(e);if(s&&!ff(s)&&!r.has(s)&&!Qe(s)){if(y(s)){t.push({severity:`warning`,rule:df,where:n,path:i,message:`${a} "${s}" carries a platform namespace prefix, but no platform package, official plugin, or cloud runtime object registers that name \u2014 and this stack does not define it either. If nothing provides it at runtime the reference resolves to nothing and fails silently.`+T(s,lf),hint:`Check the spelling against the object the providing package actually registers (e.g. "sys_approval_request", not "sys_approval_process" \u2014 the process object was removed when approval became a flow node, ADR-0019). If a third-party package genuinely provides it, this warning is expected. ${o}`});return}t.push({severity:`error`,rule:uf,where:n,path:i,message:`${a} "${s}" resolves to no object defined in this stack. The reference is inert at runtime \u2014 nothing reports the miss.`+T(s,r),hint:`Point it at one of this stack's objects, or at a platform object by its full name (the platform user object is "sys_user", not "user"). ${o}`+(r.size>0?` Defined objects: ${[...r].sort().join(`, `)}.`:``)})}},a=(e,t,n)=>{let r=w(e.params);for(let e=0;e<r.length;e++){let a=r[e];if(!a||typeof a!=`object`)continue;let o=`${n} \xB7 param "${R(a.name)??R(a.field)??`#${e}`}"`;i(R(a.reference),o,`${t}.params[${e}].reference`,`record-picker target`,`Without a resolvable target the picker degrades to a raw record-id text input.`),i(R(a.objectOverride),o,`${t}.params[${e}].objectOverride`,`field-backed param object`,`The param inherits type/options from a field on this object, so an unknown object leaves it untyped.`)}},o=w(e.actions);for(let e=0;e<o.length;e++){let t=o[e];t&&typeof t==`object`&&a(t,`actions[${e}]`,`action "${R(t.name)??`#${e}`}"`)}for(let e=0;e<n.length;e++){let t=n[e];if(!t||typeof t!=`object`)continue;let r=R(t.name)??`#${e}`,i=w(t.actions);for(let t=0;t<i.length;t++){let n=i[t];n&&typeof n==`object`&&a(n,`objects[${e}].actions[${t}]`,`object "${r}" \xB7 action "${R(n.name)??`#${t}`}"`)}}let s=w(e.dashboards);for(let e=0;e<s.length;e++){let t=s[e];if(!t||typeof t!=`object`)continue;let n=R(t.name)??`#${e}`,r=w(t.globalFilters);for(let t=0;t<r.length;t++){let a=r[t];if(!a||typeof a!=`object`)continue;let o=a.optionsFrom;o&&typeof o==`object`&&i(R(o.object),`dashboard "${n}" \xB7 filter "${R(a.name)??`#${t}`}"`,`dashboards[${e}].globalFilters[${t}].optionsFrom.object`,`filter options source`,`The dropdown fetches its options from this object; an unknown one renders an always-empty filter.`)}}let c=w(e.datasets);for(let e=0;e<c.length;e++){let t=c[e];t&&typeof t==`object`&&i(R(t.object),`dataset "${R(t.name)??`#${e}`}"`,`datasets[${e}].object`,`dataset base object`,`A dataset is the FROM of every report and dashboard widget bound to it (ADR-0021), so an unknown base object leaves every one of those surfaces querying nothing.`)}let l=w(e.apps);for(let e=0;e<l.length;e++){let t=l[e];if(!t||typeof t!=`object`)continue;let n=R(t.name)??`#${e}`,r=(e,t)=>{let a=w(e);for(let e=0;e<a.length;e++){let o=a[e];if(!o||typeof o!=`object`)continue;let s=R(o.id)??`#${e}`,c=`app "${n}" \xB7 nav "${s}"`,l=`${t}[${e}]`;i(R(o.requiresObject),c,`${l}.requiresObject`,`capability gate object`,`The entry is hidden unless this object is registered, so a typo hides it permanently — and it suppresses the nav cross-reference check that would have caught the target.`),o.requiresObject&&R(o.objectName)&&i(R(o.objectName),c,`${l}.objectName`,`navigation target`,"Declaring `requiresObject` exempts this target from the build-time check, so it is only verified here."),Array.isArray(o.children)&&r(o.children,`${l}.children`)}};r(t.navigation,`apps[${e}].navigation`);let a=w(t.areas);for(let t=0;t<a.length;t++)r(a[t]?.navigation,`apps[${e}].areas[${t}].navigation`)}return t}var mf=`nav-target-unresolved`,hf=e=>!!e&&typeof e==`object`&&!Array.isArray(e);function gf(e){return typeof e==`string`&&e.length>0?e:void 0}var _f=e=>e.includes("${")||e.includes(`{`),vf=[[`page`,`pageName`,`pages`,`page`],[`report`,`reportName`,`reports`,`report`],[`dashboard`,`dashboardName`,`dashboards`,`dashboard`]];function yf(e){let t=new Set;for(let n of w(e)){let e=gf(n.name);e&&t.add(e)}return t}function bf(e){let t=[];if(!hf(e))return t;let n=w(e.apps);if(n.length===0)return t;let r=new Map;for(let[,,t]of vf)r.set(t,yf(e[t]));for(let[e,i]of n.entries()){let n=gf(i.name)??`#${e}`,a=(e,i)=>{if(Array.isArray(e))for(let[o,s]of e.entries()){if(!hf(s))continue;let e=s,c=`${i}[${o}]`;for(let[i,a,s,l]of vf){if(e.type!==i)continue;let u=gf(e[a]);if(!u||_f(u))continue;let d=r.get(s);if(d.has(u))continue;let f=d.size===0;t.push({severity:`warning`,rule:mf,where:`app "${n}" \xB7 nav "${gf(e.id)??gf(e.label)??`#${o}`}"`,path:`${c}.${a}`,message:`Navigation targets ${l} '${u}', which this stack does not declare in \`${s}\`. `+(f?`The stack declares NO ${s} at all, so \`defineStack\`'s own cross-reference check skipped this entry entirely (it is gated on \`${s===`pages`?`pageNames`:s===`reports`?`reportNames`:`dashboardNames`}.size > 0\`) \u2014 nothing else will report it. `:``)+`The entry renders in the sidebar and resolves to nothing when clicked. If another package provides this ${l}, this is expected and advisory only.`,hint:`Declare the ${l} in \`${s}\`, correct the name, or remove the nav entry if the ${l} is gone.`})}Array.isArray(e.children)&&a(e.children,`${c}.children`)}};a(i.navigation,`apps[${e}].navigation`);for(let[t,n]of w(i.areas).entries())a(n.items,`apps[${e}].areas[${t}].items`),a(n.navigation,`apps[${e}].areas[${t}].navigation`)}return t}var xf=`view-page-unresolved`,Sf=e=>!!e&&typeof e==`object`&&!Array.isArray(e);function Cf(e){return typeof e==`string`&&e.length>0?e:void 0}var wf=e=>e.includes("${")||e.includes(`{`);function Tf(e){let t=new Set;for(let n of w(e.pages)){let e=Cf(n.name);e&&t.add(e)}return t}function Ef(e){let t=[];if(!Sf(e))return t;let n=Tf(e),r=(e,r,i)=>{if(!Sf(e))return;let a=Cf(e.pageName);if(!a||wf(a)||n.has(a))return;let o=n.size===0;t.push({severity:`warning`,rule:xf,where:r,path:`${i}.pageName`,message:`This view mounts page '${a}', which this stack does not declare in \`pages\`. `+(o?"The stack declares NO pages at all, so `defineStack`'s own cross-reference check skipped this entry entirely (it is gated on `pageNames.size > 0`) — nothing else will report it. ":``)+"The view appears in the object's view switcher and renders nothing when opened: a `page` view has no rows of its own to fall back to. If another package provides this page, this is expected and advisory only.",hint:"Declare the page in `pages`, correct `pageName`, or change the view's `type` away from `page` if the mount is no longer wanted."})};for(let[t,n]of w(e.objects).entries()){let e=Cf(n.name),i=e?`object "${e}"`:`objects[${t}]`;if(Sf(n.listViews))for(let[e,a]of Object.entries(n.listViews))r(a,`${i} \u203A listViews.${e}`,`objects[${t}].listViews.${e}`)}let i=Array.isArray(e.views)?e.views:[];for(let[e,t]of i.entries()){if(!Sf(t))continue;let n=Cf(t.name)??Cf(t.objectName)??`#${e}`;if(t.viewKind===`list`&&!Sf(t.config)&&r(t,`view "${n}" (flattened list overlay)`,`views[${e}]`),t.viewKind===`list`&&Sf(t.config)&&r(t.config,`view "${n}" (ViewItem record)`,`views[${e}].config`),Sf(t.list)&&r(t.list,`view "${n}" \u203A list`,`views[${e}].list`),Sf(t.listViews))for(let[i,a]of Object.entries(t.listViews))r(a,`view "${n}" \u203A listViews.${i}`,`views[${e}].listViews.${i}`)}return t}var Df=`nav-object-unservable`,Of=e=>!!e&&typeof e==`object`&&!Array.isArray(e);function kf(e){return typeof e==`string`&&e.length>0?e:void 0}var Af=e=>e.includes("${")||e.includes(`{`);function jf(e){let t=[];if(!Of(e))return t;let n=w(e.apps);if(n.length===0)return t;let r=new Map,i=w(e.objects);for(let[e,t]of i.entries()){let n=kf(t.name);n&&r.set(n,{enable:t.enable,path:`objects[${e}].enable`})}if(r.size===0)return t;for(let[e,i]of n.entries()){let n=kf(i.name)??`#${e}`,a=(e,i)=>{if(Array.isArray(e))for(let[o,s]of e.entries()){if(!Of(s))continue;let e=s,c=`${i}[${o}]`;if(e.type===`object`){let i=kf(e.objectName),a=i&&!Af(i)?r.get(i):void 0;if(i&&a&&!ee(a.enable,`list`)){let r=Of(a.enable)?a.enable:{},s=r.apiEnabled===!1,l=s?"`enable.apiEnabled: false`":"`enable.apiMethods` does not grant `list`"+(Array.isArray(r.apiMethods)?` (declared: ${r.apiMethods.length===0?`[] — deny-all`:r.apiMethods.map(e=>`\`${String(e)}\``).join(`, `)})`:``),u=s?"404 `OBJECT_API_DISABLED`":"405 `OBJECT_API_METHOD_NOT_ALLOWED`",d=s?`${a.path}.apiEnabled`:`${a.path}.apiMethods`;t.push({severity:`error`,rule:Df,where:`app "${n}" \xB7 nav "${kf(e.id)??kf(e.label)??`#${o}`}"`,path:`${c}.objectName`,message:`Navigation targets object "${i}", which cannot serve a list: ${l} (\`${d}\`), so the list request answers ${u} for EVERY user \u2014 platform administrators included, since that gate reads only the object's \`enable\` block and never the caller. The entry cannot be rescued with \`requiredPermissions\`: they are independent conditions. The server prunes this entry from the served \`/meta\` payload (#7912), so publishing it ships a menu row that silently is not there.`,hint:`Remove the nav entry, or make "${i}" listable by setting \`enable.apiEnabled: true\` and granting \`list\` in \`enable.apiMethods\`. \u26D4 Do NOT open the API on an object that is disabled on purpose \u2014 several platform objects hold credential material and are API-disabled deliberately; for those the entry is the mistake, not the \`enable\` block.`})}}Array.isArray(e.children)&&a(e.children,`${c}.children`)}};a(i.navigation,`apps[${e}].navigation`);for(let[t,n]of w(i.areas).entries())a(n.items,`apps[${e}].areas[${t}].items`),a(n.navigation,`apps[${e}].areas[${t}].navigation`)}return t}var Mf=`sort-field-unknown`,Nf=`sort-field-unsortable`,Pf=`sort-field-unprovisioned`;function z(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function Ff(e){return typeof e==`string`&&e.length>0?e:void 0}function If(e){let t=(e,t)=>{let n=e.trim();if(!n)return;let r=n.startsWith(`-`)?n.slice(1).trim():n.split(/\s+/)[0];return r?{field:r,at:t}:void 0};if(typeof e==`string`)return e.split(`,`).map((n,r)=>t(n,e.includes(`,`)?`[${r}]`:``)).filter(e=>!!e);if(Array.isArray(e)){let n=[];for(let r=0;r<e.length;r++){let i=e[r];if(typeof i==`string`){let e=t(i,`[${r}]`);e&&n.push(e);continue}if(!z(i))continue;let a=Ff(i.field);a&&n.push({field:a.trim(),at:`[${r}]`})}return n}return[]}function Lf(e,t,n,r,i,a,o){let s=[];if(e==null||!t||!n.has(t))return s;let c=n.get(t);if(!c)return s;let l=c.names,u=o?.get(t);for(let n of If(e)){let e=n.field,o=e.split(`.`)[0];if(bt.has(o)){!e.includes(`.`)&&u?.has(o)&&s.push({severity:`warning`,rule:Pf,where:r,path:`${i}${n.at}`,message:`${a} orders by "${e}", which resolves on object "${t}", but ${Tt(t,e)} \u2014 so the ORDER BY reaches the driver, finds no column, and is dropped. Measured on a federated object over a real remote table, 'asc' and 'desc' return BYTE-IDENTICAL row order under a 200 while the same query on a real column reverses. Unlike this rule's other two verdicts nothing refuses it: the REST ingress (#6994) and the engine (#7095) both judge only 'formula', so the view's FIRST fetch \u2014 and every fetch after it \u2014 silently answers in an arbitrary order, which 'limit'/'offset' then slice into an arbitrary page.`,hint:Et(t,e)});continue}if(!l.has(o)){let c=e.includes(`.`);s.push({severity:`error`,rule:Mf,where:r,path:`${i}${n.at}`,message:`${a} orders by "${e}", which is not a field on object "${t}". The runtime refuses the sort rather than dropping it: every load of this view answers 400 INVALID_SORT (#6994), because a sort is the view's FIRST fetch and not an optional interaction.`+(c?``:T(o,l)),hint:(c?`'sort' reaches only whole columns of "${t}" itself, never a related record's column \u2014 denormalise the value onto "${t}" (a stored field, written when the source changes) and sort by that. `:`Fix the name, or add "${e}" to ${t}.fields. `)+(l.size>0?`Object fields: ${[...l].sort().join(`, `)}.`:``)});continue}let d=c.fields[e];if(Xe(d)){let o=d?.type;s.push({severity:`error`,rule:Nf,where:r,path:`${i}${n.at}`,message:`${a} orders by "${e}" on object "${t}", a virtual '${o}' field: its value is computed on read and never stored, so no driver materialises a column to ORDER BY. Measured, an unrefused sort on one returns 'asc' and 'desc' in byte-identical order \u2014 the rows carry the values they were asked to be ordered by, unordered, under a success.`,hint:`Denormalise the value onto "${t}" (a stored field, written when the source changes) and sort by that, or drop "${e}" from this sort. At runtime both doors now refuse it with 400 INVALID_SORT \u2014 the REST ingress (#6994) and the engine itself (#7095) \u2014 so the declaration breaks the view's first fetch, and every fetch after it.`})}}return s}function Rf(e){let t=[];if(!z(e))return t;let n=Array.isArray(e.objects)?e.objects:z(e.objects)?Object.entries(e.objects).map(([e,t])=>({name:e,...t})):[],r=Ao(e),i=wt(e),a=(e,n,a,o,s)=>{t.push(...Lf(e,n,r,a,o,s,i))};for(let e=0;e<n.length;e++){let t=n[e];if(!z(t))continue;let r=Ff(t.name),i=r?`object "${r}"`:`objects[${e}]`;if(z(t.listViews))for(let[n,o]of Object.entries(t.listViews))z(o)&&a(o.sort,zf(o)??r,`${i} \u203A listViews.${n}`,`objects[${e}].listViews.${n}.sort`,`list-view sort`)}let o=Array.isArray(e.views)?e.views:[];for(let e=0;e<o.length;e++){let t=o[e];if(!z(t))continue;let n=Ff(t.name)??Ff(t.objectName)??`#${e}`,r=Ff(t.objectName)??Ff(t.object);if(t.viewKind===`list`&&!z(t.config)&&a(t.sort,zf(t)??r,`view "${n}" (flattened list overlay)`,`views[${e}].sort`,`list-view sort`),t.viewKind===`list`&&z(t.config)&&a(t.config.sort,zf(t.config)??r,`view "${n}" (ViewItem record)`,`views[${e}].config.sort`,`list-view sort`),z(t.list)&&a(t.list.sort,zf(t.list)??r,`view "${n}" \u203A list`,`views[${e}].list.sort`,`list-view sort`),z(t.listViews))for(let[i,o]of Object.entries(t.listViews))z(o)&&a(o.sort,zf(o)??r,`view "${n}" \u203A listViews.${i}`,`views[${e}].listViews.${i}.sort`,`list-view sort`)}return t}function zf(e){let t=e.data;return z(t)?Ff(t.object):void 0}var Bf=`list-view-field-unknown`,Vf=`list-view-field-dotted`;function B(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function Hf(e){return typeof e==`string`&&e.length>0?e:void 0}function Uf(e){return Array.isArray(e)?e:e&&typeof e==`object`?Object.entries(e).map(([e,t])=>({name:e,...t})):[]}var Wf={"":{lists:{filterableFields:`error`,hiddenFields:`warning`,fieldOrder:`warning`},entries:{columns:`error`}},grouping:{entries:{fields:`error`}},rowColor:{scalars:{field:`warning`}},userFilters:{entries:{fields:`error`}},kanban:{scalars:{groupByField:`error`,summarizeField:`warning`},lists:{columns:`warning`}},calendar:{scalars:{startDateField:`error`,endDateField:`warning`,titleField:`warning`,colorField:`warning`}},gantt:{scalars:{startDateField:`error`,endDateField:`error`,titleField:`error`,progressField:`warning`,dependenciesField:`warning`,colorField:`warning`,parentField:`warning`,typeField:`warning`,baselineStartField:`warning`,baselineEndField:`warning`,groupByField:`warning`,assigneeField:`warning`,effortField:`warning`},entries:{tooltipFields:`warning`,quickFilters:`error`}},timeline:{scalars:{startDateField:`error`,titleField:`error`,endDateField:`warning`,groupByField:`warning`,colorField:`warning`}},gallery:{scalars:{coverField:`warning`,titleField:`warning`},lists:{visibleFields:`warning`}},map:{scalars:{latitudeField:`error`,longitudeField:`error`,locationField:`error`,titleField:`warning`,descriptionField:`warning`}},tree:{scalars:{parentField:`error`,labelField:`warning`},lists:{fields:`warning`}}},Gf={"":{columns:`projection`,filterableFields:`filter`},userFilters:{fields:`filter`}};function Kf(e,t){return Gf[e]?.[t]}var qf=[{block:`summary`,key:`field`,severity:`error`},{block:`prefix`,key:`field`,severity:`warning`}],Jf=`Nothing resolves the name at render time: the view renders successfully with a blank, empty or wrong result, and no gate reports the miss.`;function Yf(e,t,n,r,i,a){let o=`Denormalise the value onto "${r}" (a stored field, written when the source changes) and name that.`;if(e===`projection`)return{message:`${a} "${t}" is a dotted path. A list view declares no ADR-0021 \`include\`, so it compiles no joins, and the columns are sent as the query's projection \u2014 where a dotted entry is refused by name: \`assertProjectionHasNoDottedPaths\` on the engine boundary and \`assertProjectionFieldsExist\` at the REST ingress, both \`400 INVALID_FIELD\`. The view's FIRST fetch is refused, not rendered.`,hint:`Name a whole column of "${r}" \u2014 "${n}" \u2014 and read into its value in the client, or read the related record with \`expand\`. ${o}`};let s=Se(i);if(s===null)return;let c=i?.type?`\`${i.type}\``:`an unreadable`;return{message:`${a} "${t}" is a dotted path ${s===`relation`?`whose head "${n}" is a ${c} field on object "${r}" \u2014 it stores the related record's id, not an embedded document, and a list view compiles no joins to traverse it`:s===`virtual`?`whose head "${n}" is a ${c} field on object "${r}" \u2014 its value is computed on read, so no driver materialises a column for the path to reach into`:`whose head "${n}" is a ${c} field on object "${r}" that stores a single scalar value \u2014 there is nothing beneath it for a path to reach`}. No backend serves the path, so the predicate can only match zero records: the query is REFUSED rather than answered with an empty list (\`assertFilterIsMaterializable\` and the REST ingress both answer \`400 INVALID_FIELD\`).`,hint:`Filter on a column of "${r}" itself. ${o}`}}function Xf(e){let t=[];if(!B(e))return t;let n=jt(e);if(n.size===0)return t;let r=(e,r,i,a,o,s,c=void 0)=>{let l=Hf(e);if(!l)return;let u=l.split(`.`)[0];if(!u)return;let d=Mt(n,r,u);if(Ft(d)||!d)return;let f=Pt(d,u,s),p=u!==l;if(!f){if(!p||!c)return;let e=Yf(c,l,u,r,d.kind===`ok`?d.meta:void 0,s);if(!e)return;t.push({severity:`error`,rule:Vf,where:a,path:o,message:e.message,hint:e.hint});return}t.push({severity:i,rule:Bf,where:a,path:o,message:f.message+(p?` (the head segment of the written reference "${l}"; a list view compiles no joins, so only the head can name a column here)`:``)+` ${Jf}`,hint:`Name a field that exists on "${r}", or drop the entry. ${f.detail}`})},i=(e,t,i,a)=>{if(!B(e))return;let o=e.data;if(B(o)){let e=Hf(o.provider);if(e&&e!==`object`)return}if(!t||!n.has(t)||!n.get(t))return;let s=t;for(let[t,n]of Object.entries(Wf)){let o=t===``?e:e[t];if(!B(o))continue;let c=t===``?a:`${a}.${t}`,l=t===``?i:`${i} \u203A ${t}`;for(let[e,t]of Object.entries(n.scalars??{}))r(o[e],s,t,l,`${c}.${e}`,e);for(let[e,i]of Object.entries(n.lists??{})){let n=o[e];if(!Array.isArray(n))continue;let a=Kf(t,e);n.forEach((t,n)=>{r(t,s,i,l,`${c}.${e}[${n}]`,`${e}[${n}]`,a)})}for(let[e,i]of Object.entries(n.entries??{})){let n=o[e];if(!Array.isArray(n))continue;let a=Kf(t,e);n.forEach((n,o)=>{let u=`${c}.${e}[${o}]`;if(typeof n==`string`){r(n,s,i,l,u,`${e}[${o}]`,a);return}if(B(n)&&(r(n.field,s,i,l,`${u}.field`,`${e}[${o}].field`,a),t===``&&e===`columns`))for(let t of qf){let i=n[t.block];B(i)&&r(i[t.key],s,t.severity,`${l} \u203A ${e}[${o}].${t.block}`,`${u}.${t.block}.${t.key}`,`${t.block}.${t.key}`)}})}}let c=(e,t,n)=>{e!=null&&Kt(e,n,({field:e,path:n})=>{r(e,s,`error`,t,n,`filter key`,`filter`)})};c(e.filter,`${i} \u203A filter`,`${a}.filter`);let l=(e,t,n)=>{Array.isArray(e)&&e.forEach((e,r)=>{if(!B(e))return;let i=Hf(e.name)??`#${r}`;c(e.filter,`${t}[${r}] "${i}" \u203A filter`,`${n}[${r}].filter`)})};l(e.tabs,`${i} \u203A tabs`,`${a}.tabs`),B(e.userFilters)&&l(e.userFilters.tabs,`${i} \u203A userFilters.tabs`,`${a}.userFilters.tabs`)},a=e=>{let t=e.data;return B(t)?Hf(t.object):void 0},o=Uf(e.objects);for(let e=0;e<o.length;e++){let t=o[e];if(!B(t))continue;let n=Hf(t.name),r=n?`object "${n}"`:`objects[${e}]`;if(B(t.listViews))for(let[o,s]of Object.entries(t.listViews))B(s)&&i(s,a(s)??n,`${r} \u203A listViews.${o}`,`objects[${e}].listViews.${o}`)}let s=Uf(e.views);for(let e=0;e<s.length;e++){let t=s[e];if(!B(t))continue;let n=Hf(t.name)??Hf(t.objectName)??`#${e}`,r=Hf(t.objectName)??Hf(t.object);if(t.viewKind===`list`&&!B(t.config)&&i(t,a(t)??r,`view "${n}" (flattened list overlay)`,`views[${e}]`),t.viewKind===`list`&&B(t.config)&&i(t.config,a(t.config)??r,`view "${n}" (ViewItem record)`,`views[${e}].config`),B(t.list)&&i(t.list,a(t.list)??r,`view "${n}" \u203A list`,`views[${e}].list`),B(t.listViews))for(let[o,s]of Object.entries(t.listViews))B(s)&&i(s,a(s)??r,`view "${n}" \u203A listViews.${o}`,`views[${e}].listViews.${o}`)}return t}var Zf=`object-field-ref-unknown`;function Qf(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function $f(e){return Array.isArray(e)?e:e&&typeof e==`object`?Object.entries(e).map(([e,t])=>({name:e,...t})):[]}var ep=[{block:``,key:`highlightFields`,retiredAlias:`compactLayout`,consequence:`Every consumer silently skips the entry: it drives the object's default list columns, record cards, previews and the detail highlight strip, and each of them renders one field short with no error anywhere.`,prescription:"Fix the field name, or drop the entry. `highlightFields` is ordered — the first entry wins where only one field fits (ADR-0085)."},{block:`publicSharing`,key:`redactFields`,consequence:`The redaction never applies, and it fails OPEN: records served through a share link still carry the field to whoever holds the link. A mis-spelled entry is silently indistinguishable from an entry that was never written.`,prescription:`Fix the field name so the redaction binds, or drop the entry if the field is meant to be served through share links.`}];function tp(e){let t=[];if(!Qf(e))return t;let n=jt(e);if(n.size===0)return t;let r=$f(e.objects);for(let e=0;e<r.length;e++){let i=r[e];if(!Qf(i))continue;let a=typeof i.name==`string`&&i.name.length>0?i.name:void 0;if(!a||!n.has(a)||!n.get(a))continue;let o=`object "${a}"`,s=`objects[${e}]`;for(let e of ep){let r=e.block===``?i:i[e.block];if(!Qf(r))continue;let c=e.block===``?s:`${s}.${e.block}`,l=Array.isArray(r[e.key])?e.key:e.retiredAlias&&Array.isArray(r[e.retiredAlias])?e.retiredAlias:void 0;l&&r[l].forEach((r,i)=>{if(typeof r!=`string`||r.length===0)return;let s=Mt(n,a,r);if(Ft(s)||!s)return;let u=Pt(s,r,`${l}[${i}]`);u&&t.push({severity:`error`,rule:Zf,where:`${o} \u203A ${l}`,path:`${c}.${l}[${i}]`,message:`${u.message} ${e.consequence}`,hint:`${e.prescription} ${u.detail}`})})}}return t}var np=`action-name-undefined`;function V(e){return typeof e==`string`&&e.length>0?e:void 0}function rp(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`&&e.length>0):[]}function ip(e){let t=new Set;for(let n of w(e.actions)){let e=V(n?.name);e&&t.add(e)}for(let n of w(e.objects))if(n&&typeof n==`object`)for(let e of w(n.actions)){let n=V(e?.name);n&&t.add(n)}return t}function ap(e){let t=[];if(!e||typeof e!=`object`)return t;let n=ip(e),r=(e,r,i,a,o=`with the location this surface needs`)=>{n.has(e)||t.push({severity:`error`,rule:np,where:r,path:i,message:`${a} names action "${e}", which is defined by no action in this stack (neither \`stack.actions\` nor any object's \`actions\`). The button renders and does nothing when clicked \u2014 a dead affordance the runtime cannot dispatch.`+T(e,n),hint:`Define an action named "${e}" (in \`stack.actions\` or the object's \`actions\`) ${o}, remove the reference, or ignore this if the action is contributed by another installed package.`+(n.size>0?` Defined actions: ${[...n].sort().join(`, `)}.`:``)})},i="(no `locations` entry needed — the selection bar places it by name)",a=(e,t,n,a)=>{if(!e||typeof e!=`object`)return;let o=e;for(let e of[`rowActions`,`bulkActions`]){let s=rp(o[e]);for(let o=0;o<s.length;o++)r(s[o],`${t} \xB7 ${n} \xB7 ${e}`,`${a}.${e}[${o}]`,e===`bulkActions`?`Bulk-action menu`:`Row-action menu`,e===`bulkActions`?i:void 0)}let s=Array.isArray(o.bulkActionDefs)?o.bulkActionDefs:[];for(let e=0;e<s.length;e++){let o=s[e];if(!o||typeof o!=`object`||o.execution!==`aggregate`||o.actionDef!==void 0)continue;let c=V(o.name);c&&r(c,`${t} \xB7 ${n} \xB7 bulkActionDefs[${e}]`,`${a}.bulkActionDefs[${e}].name`,`Aggregate bulk action`,i)}},o=w(e.views);for(let e=0;e<o.length;e++){let t=o[e];if(!t||typeof t!=`object`)continue;let n=`view "${V(t.name)??V(t.object)??`#${e}`}"`;a(t.list,n,`list`,`views[${e}].list`);let r=t.listViews;if(r&&typeof r==`object`&&!Array.isArray(r))for(let[t,i]of Object.entries(r))a(i,n,`listViews.${t}`,`views[${e}].listViews.${t}`)}let s=w(e.objects);for(let e=0;e<s.length;e++){let t=s[e];if(!t||typeof t!=`object`)continue;let n=t.listViews;if(!n||typeof n!=`object`||Array.isArray(n))continue;let r=`object "${V(t.name)??`#${e}`}"`;for(let[t,i]of Object.entries(n))a(i,r,`listViews.${t}`,`objects[${e}].listViews.${t}`)}let c=w(e.pages);for(let e=0;e<c.length;e++){let t=c[e];if(!t||typeof t!=`object`)continue;let n=V(t.name)??`#${e}`;for(let{component:i,path:a}of Ro(t,`pages[${e}]`)){let e=i.properties;if(!e||typeof e!=`object`)continue;let t=rp(e.actionNames);for(let e=0;e<t.length;e++)r(t[e],`page "${n}" \xB7 component "${V(i.type)??`?`}"`,`${a}.properties.actionNames[${e}]`,`Quick-actions bar`)}}let l=w(e.apps);for(let e=0;e<l.length;e++){let t=l[e];if(!t||typeof t!=`object`)continue;let n=V(t.name)??`#${e}`,i=(e,t)=>{let a=w(e);for(let e=0;e<a.length;e++){let o=a[e];if(!o||typeof o!=`object`)continue;let s=`${t}[${e}]`,c=o.actionDef,l=V(c?.actionName);o.type===`action`&&l&&r(l,`app "${n}" \xB7 nav "${V(o.id)??`#${e}`}"`,`${s}.actionDef.actionName`,`Navigation action item`);let u=V(o.runAction);o.type===`object`&&u&&r(u,`app "${n}" \xB7 nav "${V(o.id)??`#${e}`}"`,`${s}.runAction`,`Navigation deep-link auto-run`),Array.isArray(o.children)&&i(o.children,`${s}.children`)}};i(t.navigation,`apps[${e}].navigation`);let a=w(t.areas);for(let t=0;t<a.length;t++)i(a[t]?.navigation,`apps[${e}].areas[${t}].navigation`)}return t}var op=`action-no-placement`;function sp(e){return typeof e==`string`&&e.length>0?e:void 0}function cp(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`&&e.length>0):[]}function lp(e){let t=new Set,n=e=>{if(!e||typeof e!=`object`)return;let n=e;for(let e of[`rowActions`,`bulkActions`])for(let r of cp(n[e]))t.add(r);for(let e of w(n.bulkActionDefs)){let n=sp(e?.name);n&&t.add(n)}},r=e=>{if(e&&typeof e==`object`&&!Array.isArray(e))for(let t of Object.values(e))n(t)};for(let t of w(e.views))t&&typeof t==`object`&&(n(t.list),r(t.listViews));for(let t of w(e.objects))t&&typeof t==`object`&&r(t.listViews);return t}function up(e){let t=[];if(!e||typeof e!=`object`)return t;let n=lp(e),r=(e,r)=>{if(!e||typeof e!=`object`||`locations`in e)return;let i=sp(e.name);i&&(n.has(i)||t.push({severity:`warning`,rule:op,where:`action "${i}"`,path:r,message:`Action "${i}" declares no \`locations\` and no view places it by name, so it renders on no surface \u2014 the button exists in metadata and nowhere in the UI.`,hint:"Add the surface it belongs on, e.g. `locations: ['record_header']` (or `list_item`, `list_toolbar`, `record_more`, `record_section`, `record_related`); or place it from a list view's `bulkActions` / `bulkActionDefs` if it acts on a selection. If it is meant to be callable over REST / MCP / AI with no UI surface, say so explicitly with `locations: []` — an empty array is the documented headless shape and is never flagged."}))},i=w(e.actions);for(let e=0;e<i.length;e++)r(i[e],`actions[${e}]`);let a=w(e.objects);for(let e=0;e<a.length;e++){let t=a[e];if(!t||typeof t!=`object`)continue;let n=w(t.actions);for(let t=0;t<n.length;t++)r(n[t],`objects[${e}].actions[${t}]`)}return t}var dp=`page/visualization-without-binding`,fp=[{visualization:`kanban`,binding:`groupByField`,types:[`select`,`multiselect`,`radio`,`enum`,`boolean`],namePattern:`status|stage|state|priority|category|kind`,viewBlocks:[`kanban`]},{visualization:`calendar`,binding:`startDateField`,types:[`date`,`datetime`,`time`],namePattern:`date|due|start|end|deadline|schedule`,viewBlocks:[`calendar`]},{visualization:`timeline`,binding:`startDateField`,types:[`date`,`datetime`,`time`],namePattern:`date|due|start|end|deadline|schedule`,viewBlocks:[`timeline`,`calendar`]},{visualization:`gallery`,binding:`coverField`,types:[`image`,`file`,`attachment`,`avatar`,`photo`],namePattern:null,viewBlocks:[`gallery`]},{visualization:`gantt`,binding:`startDateField + endDateField`,types:[`date`,`datetime`,`time`],namePattern:null,viewBlocks:[`gantt`]},{visualization:`map`,binding:`locationField`,types:[`location`,`geo`,`geolocation`,`geopoint`,`point`],namePattern:`location|address|geo|coords?|place|venue`,viewBlocks:[`map`]}],pp=`grid`,mp=new Map(fp.map(e=>[e.visualization,e])),hp=/start|begin|kickoff/i,gp=/end|due|finish|deadline|close/i;function H(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function U(e){return typeof e==`string`&&e.length>0?e:void 0}function _p(e){let t=e.fields;if(!H(t)&&!Array.isArray(t))return;let n=0,r=[];for(let e of w(t)){let t=U(e.name);t&&(n++,!(e.hidden===!0||e.system===!0||bt.has(t))&&r.push({name:t,type:U(e.type)}))}return n===0?void 0:r}function vp(e,t){return e.find(t)?.name}function yp(e,t){let n=vp(e,e=>!!e.type&&t.types.includes(e.type));if(n)return n;if(t.namePattern===null)return;let r=new RegExp(t.namePattern,`i`);return vp(e,e=>r.test(e.name))}function bp(e,t){let n=e=>!!e.type&&t.includes(e.type),r=vp(e,e=>n(e)&&hp.test(e.name))??vp(e,n);if(!r)return;let i=vp(e,e=>n(e)&&e.name!==r&&gp.test(e.name))??vp(e,e=>n(e)&&e.name!==r);if(i)return`${r} + ${i}`}function xp(e,t){return t.visualization===`gantt`?bp(e,t.types):yp(e,t)}function Sp(e,t,n){let r=new Map,i=(e,t)=>{H(t)&&!r.has(e)&&r.set(e,t)},a=H(t?.listViews)?t.listViews:H(t?.list_views)?t.list_views:void 0;if(a)for(let[e,t]of Object.entries(a))i(e,t);t&&H(t.list)&&i(`list`,t.list);for(let t of w(e.views)){let e=U(t.objectName)??U(t.object),r=t=>(H(t.data)?U(t.data.object):void 0)??e;if(H(t.listViews))for(let[e,a]of Object.entries(t.listViews))H(a)&&r(a)===n&&i(e,a);H(t.list)&&r(t.list)===n&&i(`list`,t.list)}return r}function Cp(e){return Array.isArray(e.columns)&&e.columns.length>0}function wp(e,t,n){let r=[e.get(`${t}.${n}`),e.get(n),...n==="default"||n===`list`?[e.get(`list`)]:[]].filter(H);return r.find(Cp)??r[0]}function Tp(e,t){let n=H(e.options)?e.options:void 0;return t.viewBlocks.some(t=>H(e[t])||!!n&&H(n[t]))}function Ep(e){let t=`a field typed ${e.types.join(` / `)}`,n=e.namePattern===null?``:`, then a field whose NAME matches /${e.namePattern}/i`;return e.visualization===`gantt`?`two distinct fields typed ${e.types.join(` / `)} (a start and an end)`:`${t}${n}`}function Dp(e){let t=[];if(!H(e))return t;let n=new Map;for(let t of w(e.objects)){let e=U(t.name);e&&!n.has(e)&&n.set(e,t)}let r=w(e.pages);for(let i=0;i<r.length;i++){let a=r[i];if(a.type!==`list`)continue;let o=H(a.interfaceConfig)?a.interfaceConfig:void 0;if(!o)continue;let s=(H(o.appearance)?o.appearance:void 0)?.allowedVisualizations;if(!Array.isArray(s)||s.length===0)continue;let c=U(o.source)??U(a.object);if(!c)continue;let l=n.get(c);if(!l)continue;let u=_p(l);if(!u)continue;let d=U(o.sourceView),f;if(d&&(f=wp(Sp(e,l,c),c,d),!f))continue;let p=U(a.name)??`#${i}`,m=`page "${p}" \xB7 interfaceConfig.appearance`;for(let e=0;e<s.length;e++){let n=U(s[e]);if(!n||n===pp)continue;let r=mp.get(n);if(!r||f&&Tp(f,r)||xp(u,r))continue;let a=e===0;t.push({severity:a?`error`:`warning`,rule:dp,where:m,path:`pages[${i}].interfaceConfig.appearance.allowedVisualizations[${e}]`,message:`page "${p}" whitelists the '${n}' visualization, but nothing supplies its \`${r.binding}\`: the renderer derives that binding from "${c}"'s fields \u2014 it looks for ${Ep(r)} \u2014 and "${c}" has none`+(d?`, while the referenced view "${d}" declares no \`${r.viewBlocks[0]}:\` block either.`:`, and this page references no view that declares it.`)+` `+(a?`'${n}' LEADS \`allowedVisualizations\`, so it becomes the page's forced view type: every visitor lands on the renderer's "configuration required" refusal screen.`:`'${n}' is filtered out of the visualization switcher SILENTLY \u2014 the switcher still appears (it is shown on whitelist length), the type is simply never there, with no message at build time or at run time.`),hint:`An interface page has no per-visualization binding key of its own \u2014 \`sourceView\` is the one schema-legal channel. Point this page at a "${c}" list view that declares a \`${r.viewBlocks[0]}:\` block (\`interfaceConfig.sourceView: '<view_key>'\`), give "${c}" a field the derivation can find (${Ep(r)}), or drop '${n}' from \`appearance.allowedVisualizations\`.`})}}return t}var Op=`component-props-unknown-key`,kp=`component-props-invalid`;function Ap(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function jp(e){return typeof e==`string`&&e.length>0?e:void 0}var Mp=l,Np=`object`;function Pp(e,t){return e.path.length!==1||e.path[0]!==Np?!1:jp((Ap(t.dataSource)?t.dataSource:void 0)?.object)!==void 0}function Fp(e){if(e.code!==`invalid_union`)return;let t=e.errors;if(!t||t.length===0)return;let n;for(let e of t){let t=e.filter(e=>e.code===`unrecognized_keys`);if(t.length!==0){if(t.length!==e.length||n)return;n=t[0]}}return n}function Ip(e){let t=[];if(!Ap(e))return t;let n=w(e.pages);for(let e=0;e<n.length;e++){let r=n[e];if(!Ap(r))continue;let i=jp(r.name)??`#${e}`;for(let{component:n,path:a}of Ro(r,`pages[${e}]`)){let e=jp(n.type);if(!e)continue;let r=Mp[e];if(!r)continue;let o=Ap(n.properties)?n.properties:void 0;if(!o)continue;let s=`page "${i}" \xB7 ${e}`,c=`${a}.properties`;for(let n of b(r,o,e,c))t.push({severity:`warning`,rule:Op,where:s,path:n.path,message:`\`${n.key}\` is not a prop \`${e}\` declares (ComponentPropsMap, @objectstack/spec/ui), so nothing verifies it: \`properties\` is an untyped bag, the renderer spreads whatever it carries, and a key it does not read is ignored in silence.`+(n.suggestion?` Did you mean \`${n.suggestion}\`?`:``),hint:n.guidance??(n.suggestion?`Rename \`${n.key}\` \u2192 \`${n.suggestion}\`.`:`Remove \`${n.key}\`, or \u2014 if the component really does honour it \u2014 declare it on \`${e}\`'s props schema so the declaration and the renderer agree.`)});let l=r.safeParse(o);if(!l.success)for(let r of l.error?.issues??[]){if(Pp(r,n))continue;let i=r.path.length?`${c}.${r.path.join(`.`)}`:c,a=Fp(r);if(a){for(let n of a.keys??[])t.push({severity:`warning`,rule:Op,where:s,path:`${i}.${n}`,message:`\`${n}\` is not a prop \`${e}\` declares (ComponentPropsMap, @objectstack/spec/ui): ${a.message}`,hint:`Remove \`${n}\`, or declare it on \`${e}\`'s props schema if the component honours it.`});continue}if(r.code===`unrecognized_keys`){for(let n of r.keys??[])t.push({severity:`warning`,rule:Op,where:s,path:`${i}.${n}`,message:`\`${n}\` is not a prop \`${e}\` declares (ComponentPropsMap, @objectstack/spec/ui): ${r.message}`,hint:`Remove \`${n}\`, or declare it on \`${e}\`'s props schema if the component honours it.`});continue}t.push({severity:`warning`,rule:kp,where:s,path:i,message:`${i.slice(c.length+1)||`properties`}: ${os(r,o)}`,hint:`\`${e}\`'s props are declared by ComponentPropsMap (@objectstack/spec/ui) \u2014 the rejection above carries the fix. Advisory for now: the props bag is not parsed on the storage path either, so nothing rejects this today (objectstack#5068).`})}}}return t}var Lp=`component-type-unknown`;function Rp(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function zp(e){return typeof e==`string`&&e.length>0?e:void 0}function Bp(e){let t=[];if(!Rp(e))return t;let n=w(e.pages);for(let e=0;e<n.length;e++){let r=n[e];if(!Rp(r))continue;let i=zp(r.name)??`#${e}`;for(let{component:n,path:a}of Ro(r,`pages[${e}]`)){let e=zp(n.type);if(!e||!c(e)||ie(e))continue;let r=g(e,$e),o=x(r);t.push({severity:`error`,rule:Lp,where:`page "${i}" \xB7 ${e}`,path:`${a}.type`,message:`\`${e}\` is not a component type the platform vocabulary declares. Its namespace (\`${e.slice(0,e.indexOf(`:`))}:\`) belongs to the standard component vocabulary, so nothing will ever render this node \u2014 the page would validate, publish, and then draw a placeholder scaffold in front of the end user.`+(o?` ${o}`:``),hint:r.length?`Rename \`${e}\` \u2192 \`${r[0]}\`.`:`Use a declared component type from the standard vocabulary, or \u2014 for a custom component registered by your own plugin \u2014 give it its own namespace (e.g. \`my-plugin:${e.slice(e.indexOf(`:`)+1)}\`) so it cannot be mistaken for platform vocabulary.`})}}return t}var Vp=`chart-dimension-unknown`,Hp=`chart-measure-unknown`,Up=`chart-dataset-unknown`,Wp=`chart-axis-not-selected`;function W(e){return typeof e==`string`&&e.length>0?e:void 0}function Gp(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`&&e.length>0):[]}function Kp(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function qp(e){let t=[...e].sort();return t.length?t.join(`, `):`(none)`}function Jp(e){let t=new Map;for(let n of w(e.datasets)){let e=W(n.name);if(!e)continue;let r=new Set;for(let e of w(n.dimensions)){let t=W(e.name);t&&r.add(t)}let i=new Set;for(let e of w(n.measures)){let t=W(e.name);t&&i.add(t)}t.set(e,{dimensions:r,measures:i})}return t}var Yp={"report-series":"On this surface `chart.series[]` is a per-measure DISPLAY-NAME override, not a binding: the renderer derives the series from the chart's own `xAxis`/`yAxis` query and pairs an authored entry with the derived series whose key it EQUALS, so an entry naming no declared measure is ignored. The override lands on nothing — the series is still drawn from the dataset selection.","page-series":"On this surface `series[]` is presentation, not a binding: the renderer derives one series per selected measure and REPLACES the authored array with the derived one, so this entry never reaches the chart at all. It lands on nothing — the chart is still drawn from `dimensions`/`values`.","page-axis":"On this surface `yAxis[].field` is axis PRESENTATION, not a binding: the entry keeps its slot (the count is what turns on a secondary axis) and its scale/chrome, while the plotted columns come from `values`. The key re-points nothing."},Xp={"report-series":"`series[].name` selects WHICH derived series the label and per-series presentation land on; it cannot add, remove or re-point one.","page-series":"`series[].name` cannot add, remove or re-point a series on a dataset-bound chart — membership belongs to the dataset selection.","page-axis":"`yAxis[]` carries presentation only (title, min/max, position, gridlines); the plotted columns come from `values`."},Zp={query:`the query does not return it, so the series plots nothing.`,"report-series":"this entry is a display-name override matched against the ONE series the chart derives (from its own `chart.yAxis` query), so unless it names that measure the override lands on nothing. The series drawn is unaffected.","page-series":"the series are derived from `values`, so none is derived for it and this entry lands on nothing. The chart drawn is unaffected.","page-axis":"the plotted columns come from `values`, so the axis entry re-points nothing. The chart drawn is unaffected."};function Qp(e){let t=[];if(!e||typeof e!=`object`)return t;let n=Jp(e);if(n.size===0&&!e.reports&&!e.views&&!e.pages)return t;let r=(e,r,i)=>{if(!e)return;let a=n.get(e);if(a)return a;t.push({severity:`error`,rule:Up,where:r,path:`${i}.dataset`,message:`binds dataset "${e}", which resolves to no declared dataset \u2014 there is no data to render.`,hint:`Declared datasets: ${qp(n.keys())}.${T(e,n.keys())} Define it with defineDataset() or fix the reference (ADR-0021).`})},i=(e,n,r)=>{let i=(i,a)=>{e.dimensions.has(i)||t.push({severity:`error`,rule:Vp,where:r.where,path:a,message:`"${i}" is not a dimension declared by dataset "${n}". Post-ADR-0021 result rows are keyed by DIMENSION NAME, not the base field, so this axis renders with no categories.`,hint:`Dataset dimensions: ${qp(e.dimensions)}.${T(i,e.dimensions)} Declare the dimension on the dataset, or bind an existing one.`})},a=(i,a,o,s)=>{if(!e.measures.has(i)){t.push({severity:o===`query`?`error`:`warning`,rule:Hp,where:r.where,path:a,message:`"${i}" is not a measure declared by dataset "${n}". `+(o===`query`?`Post-ADR-0021 result rows are keyed by MEASURE NAME (e.g. "sum_amount"), not the base field (e.g. "amount"), so this series comes back empty.`:Yp[o]),hint:`Dataset measures: ${qp(e.measures)}.${T(i,e.measures)} `+(o===`query`?`Declare the measure on the dataset, or bind an existing one.`:`${Xp[o]} Correct the name or drop the entry \u2014 this surface carries no \`suppressWarnings\` key to silence the advisory with.`)});return}s&&s.size>0&&!s.has(i)&&t.push({severity:`warning`,rule:Wp,where:r.where,path:a,message:`"${i}" is a declared measure of "${n}" but is not in this chart's selected values (${qp(s)}) \u2014 ${Zp[o]}`,hint:o===`report-series`?"Point the entry at the measure this chart plots (`chart.yAxis`), or drop it.":`Add "${i}" to \`values\`, or point the ${o===`query`?`axis`:`entry`} at a selected measure.`})};for(let e of r.dimensions??[])for(let t=0;t<e.names.length;t++)i(e.names[t],`${e.path}[${t}]`);let o=r.values,s=new Set(o?.names??[]),c=r.ownSelection?new Set(r.ownSelection):s;if(o)for(let e=0;e<o.names.length;e++)a(o.names[e],`${o.path}[${e}]`,`query`);r.xAxis&&i(r.xAxis.name,r.xAxis.path),r.yAxis&&a(r.yAxis.name,r.yAxis.path,`query`);for(let e of r.axes??[])a(e.name,e.path,`page-axis`,c);for(let e of r.series??[])a(e.name,e.path,e.kind,c)},a=e=>{let t=r(e.dataset,e.where,e.path);t&&e.dataset&&i(t,e.dataset,e)},o=w(e.reports);for(let e=0;e<o.length;e++){let t=o[e];if(!Kp(t))continue;let n=W(t.name)??`#${e}`,a=(e,t,n)=>{let a=W(e.dataset),o=r(a,t,n);if(!o||!a)return;i(o,a,{dimensions:[{names:Gp(e.rows),path:`${n}.rows`},{names:Gp(e.columns),path:`${n}.columns`}],values:{names:Gp(e.values),path:`${n}.values`},where:t,path:n});let s=e.chart;if(!Kp(s))return;let c=W(s.xAxis),l=W(s.yAxis);i(o,a,{xAxis:c?{name:c,path:`${n}.chart.xAxis`}:void 0,yAxis:l?{name:l,path:`${n}.chart.yAxis`}:void 0,ownSelection:l?[l]:[],series:w(s.series).map((e,t)=>({name:W(e.name),path:`${n}.chart.series[${t}].name`,kind:`report-series`})).filter(e=>!!e.name),where:`${t} \xB7 chart`,path:`${n}.chart`})};a(t,`report "${n}"`,`reports[${e}]`);let s=Array.isArray(t.blocks)?t.blocks:[];for(let t=0;t<s.length;t++){let r=s[t];Kp(r)&&a(r,`report "${n}" \xB7 block "${W(r.name)??`#${t}`}"`,`reports[${e}].blocks[${t}]`)}}let s=(e,t,n)=>{if(!Kp(e))return;let r=e.chart;Kp(r)&&a({dataset:W(r.dataset),dimensions:[{names:Gp(r.dimensions),path:`${n}.chart.dimensions`}],values:{names:Gp(r.values),path:`${n}.chart.values`},where:t,path:`${n}.chart`})},c=w(e.views);for(let e=0;e<c.length;e++){let t=c[e];if(!Kp(t))continue;let n=W(t.name)??W(t.objectName)??`#${e}`;if(s(t.list,`view "${n}" \xB7 list chart`,`views[${e}].list`),Kp(t.listViews))for(let[r,i]of Object.entries(t.listViews))s(i,`view "${n}" \xB7 listViews.${r} chart`,`views[${e}].listViews.${r}`)}let l=w(e.objects);for(let e=0;e<l.length;e++){let t=l[e];if(!Kp(t)||!Kp(t.listViews))continue;let n=W(t.name)??`#${e}`;for(let[r,i]of Object.entries(t.listViews))s(i,`object "${n}" \xB7 listViews.${r} chart`,`objects[${e}].listViews.${r}`)}let u=w(e.pages);for(let e=0;e<u.length;e++){let t=u[e];if(!Kp(t))continue;let n=W(t.name)??`#${e}`;for(let{component:r,path:i}of Ro(t,`pages[${e}]`)){let e=Kp(r.properties)?r.properties:void 0;if(!e||!W(e.dataset))continue;let t=w(e.yAxis).map((e,t)=>({name:W(e.field),path:`${i}.properties.yAxis[${t}].field`})).filter(e=>!!e.name),o=w(e.series).map((e,t)=>({name:W(e.name),path:`${i}.properties.series[${t}].name`,kind:`page-series`})).filter(e=>!!e.name);a({dataset:W(e.dataset),dimensions:[{names:Gp(e.dimensions),path:`${i}.properties.dimensions`}],values:{names:Gp(e.values),path:`${i}.properties.values`},axes:t,series:o,where:`page "${n}" \xB7 ${W(r.type)??`chart`}`,path:`${i}.properties`})}}return t}var $p=`dataset-include-unknown`,em=`dataset-field-unknown`,tm=`dataset-field-not-included`,nm=`dataset-filter-field-unknown`;function rm(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function im(e){return typeof e==`string`&&e.length>0?e:void 0}var am=`The path is compiled into the analytics query as written, so it addresses a column that does not exist: the surface renders successfully with empty or wrong numbers, and nothing reports the miss.`;function om(e){let t=[];if(!rm(e))return t;let n=w(e.datasets);if(n.length===0)return t;let r=jt(e);return n.forEach((e,n)=>{let i=`dataset "${im(e.name)??`#${n}`}"`,a=`datasets[${n}]`,o=im(e.object);if(!o||!r.has(o)||!r.get(o))return;let s=Nt(e.include);(Array.isArray(e.include)?e.include:[]).forEach((e,n)=>{if(typeof e!=`string`||!e)return;let s=`${a}.include[${n}]`,c=Mt(r,o,e);if(Ft(c)||!c)return;let l=`Declare a relationship (lookup / master_detail) that exists on the join chain from "${o}", or drop the entry. ADR-0071 allows up to 3 hops and declaring "a.b" implicitly includes "a".`;if(c.kind===`ok`){if(c.injected)return;let r=c.meta?.type;if(r&&Dt.has(r))return;t.push({severity:`error`,rule:$p,where:i,path:s,message:`include[${n}] "${e}" names a${r?` \`${r}\``:`n ordinary`} field on object "${c.object}", not a relationship \u2014 no join can be derived from it, so every dimension or measure written against that prefix addresses nothing.`,hint:l});return}let u=Pt(c,e,`include[${n}]`);u&&t.push({severity:`error`,rule:$p,where:i,path:s,message:`${u.message} Joins are COMPILED from \`include\` (ADR-0021), so an entry that resolves to nothing produces no join at all.`,hint:`${l} ${u.detail}`})});let c=(e,n,i,a,c,l)=>{let u=im(e);if(!u)return;let d=Mt(r,o,u);if(Ft(d)||!d)return;let f=Pt(d,u,a);if(f){t.push({severity:`error`,rule:c,where:n,path:i,message:`${f.message} ${am}`,hint:`${l} ${f.detail}`});return}let p=u.lastIndexOf(`.`);if(p<0)return;let m=u.slice(0,p);s.has(m)||t.push({severity:`error`,rule:tm,where:n,path:i,message:`${a} "${u}" resolves on the object graph, but its relationship prefix "${m}" is not declared in this dataset's \`include\` \u2014 and ADR-0021 joins ONLY declared paths, so no join is compiled and the column is out of the query's reach. ${am}`,hint:`Add "${m}" to include (declaring "a.b" implicitly includes "a"), or bind this position to a field on "${o}" itself. Declared include paths: ${s.size>0?[...s].sort().join(`, `):`(none)`}.`})};w(e.dimensions).forEach((e,t)=>{let n=im(e.name)??`#${t}`;c(e.field,`${i} \u203A dimension "${n}"`,`${a}.dimensions[${t}].field`,`dimension field`,em,`Bind the dimension to a field on "${o}", or to a \`relationship[.relationship].field\` path whose prefix is declared in \`include\`.`)}),w(e.measures).forEach((e,t)=>{let n=im(e.name)??`#${t}`;c(e.field,`${i} \u203A measure "${n}"`,`${a}.measures[${t}].field`,`measure field`,em,`Bind the measure to a field on "${o}", or to a \`relationship[.relationship].field\` path whose prefix is declared in \`include\`.`)});let l=(e,t,n)=>{e!=null&&Kt(e,n,({field:e,path:n})=>{c(e,t,n,`filter key`,nm,`Filter on a field that exists on "${o}" (or on a declared \`include\` path).`)})};l(e.filter,`${i} \u203A filter`,`${a}.filter`),w(e.measures).forEach((e,t)=>{let n=im(e.name)??`#${t}`;l(e.filter,`${i} \u203A measure "${n}" \u203A filter`,`${a}.measures[${t}].filter`)})}),t}var sm=`validation-rule-regex-uncompilable`,cm=`validation-rule-json-schema-uncompilable`,lm={allErrors:!0,strict:!1},um=e=>!!e&&typeof e==`object`&&!Array.isArray(e),dm=null,fm=null;function pm(){if(dm)return dm;let e=import.meta.url?import.meta.url:typeof __filename<`u`?__filename:process.cwd()+`/`,t;try{t=(0,C.createRequire)(e)(`ajv`)}catch(e){throw Error(`@objectstack/lint: checking a \`json_schema\` validation rule requires the "ajv" package, which could not be loaded (${e instanceof Error?e.message:String(e)}). It is a declared dependency of @objectstack/lint \u2014 if this deployment prunes packages, keep "ajv" in the image; it is only loaded when a stack declares a \`json_schema\` validation rule.`)}let n=um(t)&&`default`in t?t.default:t;return dm=n,n}function mm(){if(fm)return fm;let e=import.meta.url?import.meta.url:typeof __filename<`u`?__filename:process.cwd()+`/`,t;try{t=(0,C.createRequire)(e)(`ajv-formats`)}catch(e){throw Error(`@objectstack/lint: checking a \`json_schema\` validation rule requires the "ajv-formats" package, which could not be loaded (${e instanceof Error?e.message:String(e)}). It is a declared dependency of @objectstack/lint \u2014 if this deployment prunes packages, keep "ajv-formats" in the image; it is only loaded when a stack declares a \`json_schema\` validation rule. The runtime registers it too, and this gate must compile in the SAME environment or it starts disagreeing with the write path.`)}let n=um(t)&&`default`in t?t.default:t;return fm=n,n}function hm(){let e=new(pm())(lm);return mm()(e),e}function gm(){let e=Object.keys(hm().formats).sort();if(e.length===0)throw Error('@objectstack/lint: the runtime-parity ajv instance has no `format` registered. "ajv-formats" loaded but added nothing, so the set of legitimate format names is unknown — refusing to judge format names against an empty vocabulary, which would report every `format` in the stack as misspelled. Check that the installed "ajv-formats" is the real package and matches the version @objectstack/lint declares.');return e}function _m(e){return e instanceof Error?e.message:String(e)}var vm=16;function ym(e,t,n,r=0){let i=typeof e.name==`string`&&e.name?e.name:`?`,a=t?`${t} \u2192 '${i}'`:`'${i}'`,o=n?`${n}.${i}`:i,s=[{rule:e,label:a,path:o}];if(r>=vm)return s;for(let t of[`then`,`otherwise`]){let n=e[t];um(n)&&s.push(...ym(n,a,`${o}.${t}`,r+1))}return s}function bm(e){let t=[];if(!um(e))return t;for(let n of w(e.objects)){let e=typeof n.name==`string`?n.name:`(unnamed object)`,r=n.validations;for(let n of w(r))for(let{rule:r,label:i,path:a}of ym(n,``,``))t.push({rule:r,objectName:e,label:i,where:`object '${e}' \xB7 validation ${i}`,basePath:`objects.${e}.validations.${a}`})}return t}function xm(e){let t=[];for(let{rule:n,objectName:r,label:i,where:a,basePath:o}of bm(e)){if(n.type===`format`&&typeof n.regex==`string`&&n.regex!==``)try{new RegExp(n.regex)}catch(e){t.push({severity:`error`,rule:sm,where:a,path:`${o}.regex`,message:`\`format\` validation ${i} on object '${r}' declares a \`regex\` that does not compile: ${_m(e)}. The write path builds it with \`new RegExp(rule.regex)\` and SKIPS the rule when that throws (rule-validator.ts \`checkFormat\`), so the rule is declared, listed in the metadata, and enforces nothing on any record.`,hint:`Fix the pattern so \`new RegExp('${n.regex}')\` compiles \u2014 a literal \`(\`, \`[\` or \`\\\` must be escaped (\`\\\\(\`, \`\\\\[\`, \`\\\\\\\\\`), and the source is a STRING, so a backslash is written twice in TypeScript ('^\\\\d{2}-\\\\d{7}$'). Or drop \`regex\` and use a named \`format\` ('email' | 'url' | 'phone' | 'json').`})}if(n.type===`json_schema`&&um(n.schema))try{hm().compile(n.schema)}catch(e){t.push({severity:`error`,rule:cm,where:a,path:`${o}.schema`,message:`\`json_schema\` validation ${i} on object '${r}' declares a \`schema\` ajv cannot compile: ${_m(e)}. The write path compiles it with the same ajv (\`new Ajv({ allErrors: true, strict: false })\` + \`ajv-formats\`) and SKIPS the rule when that throws (rule-validator.ts \`checkJsonSchema\`), so the rule is declared and enforces nothing on any record.`,hint:"Correct the schema so ajv compiles it — the message above names the offending keyword. `type` must be one of null|boolean|object|array|number|string|integer (or an array of those), `required` an array of strings, and every `$ref` must resolve. Vendor keywords are fine (the runtime runs `strict: false`); a MALFORMED standard keyword is not."})}}return t}var Sm=`validation-rule-json-schema-unknown-format`,Cm=e=>!!e&&typeof e==`object`&&!Array.isArray(e),wm=[`additionalItems`,`additionalProperties`,`contains`,`propertyNames`,`if`,`then`,`else`,`not`,`unevaluatedItems`,`unevaluatedProperties`],Tm=[`allOf`,`anyOf`,`oneOf`,`prefixItems`],Em=[`properties`,`patternProperties`,`$defs`,`definitions`,`dependentSchemas`],Dm=32,Om=e=>e.replace(/~/g,`~0`).replace(/\//g,`~1`);function km(e,t,n,r){if(!Cm(e)||(typeof e.format==`string`&&n.push({pointer:`${t}/format`,name:e.format}),r>=32))return;for(let i of wm)i in e&&km(e[i],`${t}/${Om(i)}`,n,r+1);for(let i of Tm){let a=e[i];Array.isArray(a)&&a.forEach((e,a)=>{km(e,`${t}/${Om(i)}/${a}`,n,r+1)})}for(let i of Em){let a=e[i];if(Cm(a))for(let[e,o]of Object.entries(a))km(o,`${t}/${Om(i)}/${Om(e)}`,n,r+1)}let i=e.items;Array.isArray(i)?i.forEach((e,i)=>km(e,`${t}/items/${i}`,n,r+1)):Cm(i)&&km(i,`${t}/items`,n,r+1);let a=e.dependencies;if(Cm(a))for(let[e,i]of Object.entries(a))Cm(i)&&km(i,`${t}/dependencies/${Om(e)}`,n,r+1)}function Am(e,t){let n=Array.from({length:t.length+1},(e,t)=>t);for(let r=1;r<=e.length;r++){let i=[r];for(let a=1;a<=t.length;a++)i[a]=Math.min(n[a]+1,i[a-1]+1,n[a-1]+(e[r-1]===t[a-1]?0:1));n=i}return n[t.length]}function jm(e,t){let n=Math.min(3,Math.floor(e.length/2));if(n<1)return null;let r=e.toLowerCase(),i=null,a=1/0;for(let e of[...t].sort()){let t=Am(r,e);t<a&&(a=t,i=e)}return a<=n?i:null}function Mm(e){let t=[],n=[];for(let{rule:t,objectName:r,label:i,where:a,basePath:o}of bm(e)){if(t.type!==`json_schema`||!Cm(t.schema))continue;let e=[];km(t.schema,``,e,0);for(let t of e)n.push({use:t,where:a,label:i,objectName:r,basePath:o})}if(n.length===0)return t;let r=gm(),i=new Set(r);for(let{use:e,where:a,label:o,objectName:s,basePath:c}of n){if(i.has(e.name))continue;let n=jm(e.name,r),l=`#${e.pointer}`;t.push({severity:`error`,rule:Sm,where:a,path:`${c}.schema${l}`,message:`\`json_schema\` validation ${o} on object '${s}' names \`format: '${e.name}'\` at \`${l}\`, which is not a registered format. ajv logs \`unknown format "${e.name}" ignored\` once at compile time and DROPS the keyword \u2014 in the write path (rule-validator.ts, \`strict: false\`) and in the publish gate alike \u2014 so the schema compiles, the rule ships and runs on every write, its \`type\`/\`required\` keywords are enforced, and this constraint is enforced on no record, ever. The record is ACCEPTED, so nothing downstream reports the gap either.`,hint:(n?`Did you mean \`format: '${n}'\`? `:``)+`The registered names are: ${r.join(`, `)} \u2014 the default \`ajv-formats\` set, the one \`rule-validator.ts\` registers (#5029). Names are case-sensitive and hyphenated (\`date-time\`, not \`datetime\`). If you meant a constraint ajv has no format for, express it with \`pattern\` instead \u2014 a regex is enforced, an unknown format name is not.`})}return t}function Nm(e){let t=[];if(!e||typeof e!=`object`)return{version:1,entries:t};let n=new Map;for(let t of w(e.objects)){let e=typeof t.name==`string`?t.name:``;if(!e)continue;let r=t.sharingModel??t.security?.sharingModel;typeof r==`string`&&n.set(e,r)}for(let r of w(e.permissions)){let e=typeof r.name==`string`?r.name:``;if(!e)continue;let i=r.objects&&typeof r.objects==`object`?r.objects:{};for(let[r,a]of Object.entries(i)){let i=a??{},o={permissionSet:e,object:r,create:i.allowCreate===!0,read:i.allowRead===!0||i.viewAllRecords===!0||i.modifyAllRecords===!0,edit:i.allowEdit===!0||i.modifyAllRecords===!0,delete:i.allowDelete===!0||i.modifyAllRecords===!0,viewAllRecords:i.viewAllRecords===!0,modifyAllRecords:i.modifyAllRecords===!0};typeof i.readScope==`string`&&(o.readScope=i.readScope),typeof i.writeScope==`string`&&(o.writeScope=i.writeScope);let s=n.get(r);s&&(o.sharingModel=s),t.push(o)}}return t.sort((e,t)=>e.permissionSet===t.permissionSet?e.object.localeCompare(t.object):e.permissionSet.localeCompare(t.permissionSet)),{version:1,entries:t}}var Pm=[[`create`,`create`],[`read`,`read`],[`edit`,`edit`],[`delete`,`delete`],[`viewAllRecords`,`View All Data`],[`modifyAllRecords`,`Modify All Data`]];function Fm(e,t){let n=[],r=e=>`${e.permissionSet}\0${e.object}`,i=new Map((e?.entries??[]).map(e=>[r(e),e])),a=new Map((t?.entries??[]).map(e=>[r(e),e]));for(let[e,t]of i)a.has(e)||n.push(`'${t.permissionSet}' loses ALL access to '${t.object}' (entry removed)`);for(let[e,t]of a){let r=i.get(e);if(!r){let e=Pm.filter(([e])=>t[e]===!0).map(([,e])=>e);n.push(`'${t.permissionSet}' gains access to '${t.object}' (${e.join(`, `)||`no bits set`})`);continue}for(let[e,i]of Pm)r[e]!==t[e]&&n.push(`'${t.permissionSet}' ${t[e]?`gains`:`loses`} ${i} on '${t.object}'`);(r.readScope??`own`)!==(t.readScope??`own`)&&n.push(`'${t.permissionSet}' read depth on '${t.object}': ${r.readScope??`own`} \u2192 ${t.readScope??`own`}`),(r.writeScope??`own`)!==(t.writeScope??`own`)&&n.push(`'${t.permissionSet}' write depth on '${t.object}': ${r.writeScope??`own`} \u2192 ${t.writeScope??`own`}`),(r.sharingModel??``)!==(t.sharingModel??``)&&n.push(`'${t.object}' record baseline (OWD): ${r.sharingModel??`(unset)`} \u2192 ${t.sharingModel??`(unset)`} (affects every principal)`)}return n}var Im=`nav-object-ungranted`;function Lm(e){return typeof e==`string`&&e.length>0?e:void 0}function Rm(e){let t=[],n=w(e.apps);for(let e=0;e<n.length;e++){let r=n[e];if(!r||typeof r!=`object`)continue;let i=Lm(r.name)??`#${e}`,a=(e,n)=>{let r=w(e);for(let e=0;e<r.length;e++){let o=r[e];if(!o||typeof o!=`object`)continue;let s=`${n}[${e}]`,c=Lm(o.objectName);o.type===`object`&&c&&t.push({objectName:c,where:`app "${i}" \xB7 nav "${Lm(o.id)??`#${e}`}"`,path:`${s}.objectName`}),Array.isArray(o.children)&&a(o.children,`${s}.children`)}};a(r.navigation,`apps[${e}].navigation`);let o=w(r.areas);for(let t=0;t<o.length;t++)a(o[t]?.navigation,`apps[${e}].areas[${t}].navigation`)}return t}function zm(e){let t=[];if(!e||typeof e!=`object`||w(e.permissions).length===0)return t;let n=Rm(e);if(n.length===0)return t;let r=new Set;for(let t of w(e.objects)){let e=Lm(t.name);e&&r.add(e)}let i=new Set;for(let t of Nm(e).entries)t.read&&i.add(t.object);if(i.has(`*`))return t;let a=new Set;for(let e of n){let{objectName:n}=e;a.has(n)||Qe(n)||r.has(n)&&(i.has(n)||(a.add(n),t.push({severity:`warning`,rule:Im,where:e.where,path:e.path,message:`navigation exposes object "${n}", but no permission set this stack declares grants read on it \u2014 the entry renders, and opening it fails permission-denied for every principal except one holding the platform's built-in wildcard admin set. It works when you browse as an administrator and breaks for the users the app ships permission sets for.`,hint:`Add "${n}" to a permission set's \`objects\` with \`allowRead: true\` (or \`viewAllRecords\`), or drop the entry. Gating it with \`requiredPermissions\`/\`visible\` does not clear this: those gate visibility, not the object grant, so a holder can still open the entry and hit permission-denied. Ignore this if a permission set from another installed package grants it.`})))}return t}var Bm=`field-no-consumers`;function Vm(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function Hm(e){return typeof e==`string`&&e.length>0?e:void 0}var Um=[`objects`,`views`,`pages`,`apps`,`flows`,`dashboards`,`reports`,`datasets`,`actions`,`hooks`,`jobs`,`emailTemplates`,`agents`,`tools`,`skills`,`apis`,`webhooks`,`sharingRules`,`analyticsCubes`],Wm=[`translations`,`data`,`mappings`,`permissions`],Gm=new Set([`views`,`pages`,`apps`]),Km=new Set([`label`,`pluralLabel`,`description`,`message`,`successMessage`,`errorMessage`,`title`,`placeholder`,`helpText`,`emptyText`,`tooltip`,`subtitle`]),qm=new Set(`filter.filters.runtimeFilter.relatedListFilter.where.criteria.conditions.condition.defaultFilter.userFilters.quickFilters.filterableFields.sort.sortBy.defaultSort.grouping.groupBy.groupByField.groupField.startField.endField.dateField.startDateField.endDateField.coverField.titleField.colorField.latitudeField.longitudeField.locationField.addressField.parentField.statusField.kanban.calendar.gantt.timeline.map.tree.rowColor.rowTint.conditionalFormatting.expression.formula.visibleWhen.readonlyWhen.requiredWhen.validations.rules.summaryOperations.dimensions.measures.handler.body.script.nameField.displayNameField.externalId.upsertKey`.split(`.`)),Jm=new Set([`highlightFields`,`searchableFields`,`indexes`,`columns`,`sections`,`groups`,`hideFields`,`hiddenFields`,`fieldOrder`,`visibleFields`,`labelField`,`displayField`,`descriptionField`,`tooltipFields`,`fieldGroups`,`recordTypes`,`listViews`]),Ym=new Set([`filter`,`filters`,`runtimeFilter`,`relatedListFilter`,`where`,`criteria`,`defaultFilter`,`conditions`]),Xm=new Set([`fields`,`values`,`set`,`record`,`data`,`input`,`defaults`,`records`]),Zm=new Set(`type.reference.accept.provider.dialect.operator.aggregate.mode.severity.language.surface.format.icon.variant.colorVariant.align.order.defaultValue.value.sourceFormat.transform.name.id.events.locations.version.width.cardSize.coverFit.env.pinned.summary.chartType.dateGranularity.kind.template.status.runAs.sharingModel.objectName.object.targetObject.dataset.outputVariable.triggerType.event.currency.color.size.layout.function.direction.model.role.method.path.url.key.locale.namespace.engine.driver`.split(`.`)),Qm=[/\.([A-Za-z_][A-Za-z0-9_]*)\b/g,/['"`]([A-Za-z_][A-Za-z0-9_]*)['"`]/g,/\{([A-Za-z_][A-Za-z0-9_]*)\}/g,/\b([A-Za-z_][A-Za-z0-9_]*)\s*:/g],$m=new Set([`source`,`expression`,`formula`,`condition`,`criteria`,`when`,`visibleWhen`,`readonlyWhen`,`requiredWhen`,`where`,`predicate`,`script`,`body`,`handler`,`code`]),eh=/\b([A-Za-z_][A-Za-z0-9_]*)\b/g,th=2e5,nh=class{constructor(){this.fieldsByObject=new Map,this.objectsByField=new Map,this.datasetObject=new Map,this.sites=new Map,this.unresolved=0}declare(e,t){let n=this.fieldsByObject.get(e);n||this.fieldsByObject.set(e,n=new Set),n.add(t);let r=this.objectsByField.get(t);r||this.objectsByField.set(t,r=new Set),r.add(e)}declares(e,t){return e!==void 0&&(this.fieldsByObject.get(e)?.has(t)??!1)}isObject(e){return typeof e==`string`&&this.fieldsByObject.has(e)}record(e,t,n){let r=`${e}.${t}`,i=this.sites.get(r);i?i.push(n):this.sites.set(r,[n])}mentionsIn(e){if(!this.mentionRe){let e=[...this.fieldsByObject.keys()].sort((e,t)=>t.length-e.length).map(e=>e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`));this.mentionRe=e.length>0?RegExp(`\\b(?:${e.join(`|`)})\\b`,`g`):/(?!)/g}let t=[];for(let n of e.matchAll(this.mentionRe))t.push({end:(n.index??0)+n[0].length,object:n[0]});return t}};function rh(e,t,n){return Wm.includes(e)||Km.has(n)?`carrier`:t.some(e=>qm.has(e))?`behaviour`:Gm.has(e)||t.some(e=>Jm.has(e))?`display`:`behaviour`}function ih(e,t,n,r,i,a,o){if(t.length===0||t.length>th||Zm.has(o))return;let s=[],c=t.trim();e.objectsByField.has(c)&&s.push({token:c,at:0});let l=$m.has(o)?[...Qm,eh]:Qm;for(let n of l)for(let r of t.matchAll(n))e.objectsByField.has(r[1])&&s.push({token:r[1],at:(r.index??0)+r[0].indexOf(r[1])});if(s.length===0)return;let u=e.mentionsIn(t),d=[...t.matchAll(/\{[^{}]*\}/g)].map(e=>[e.index??0,(e.index??0)+e[0].length]),f=Km.has(o);for(let{token:t,at:c}of s){let s=d.some(([e,t])=>c>=e&&c<t),l=f&&!s?`carrier`:rh(r,a,s?``:o),p;for(let e of u)if(e.end<=c)p=e.object;else break;let m=p!==void 0&&p!==n?[p,n]:[n],h=!1;for(let n of m)e.declares(n,t)&&(e.record(n,t,{root:r,path:i,kind:l}),h=!0);h||(e.unresolved+=1)}}function ah(e,t,n){let r=t=>e.isObject(t)?t:void 0,i=(e,t)=>Vm(e)?r(e[t]):void 0,a=Vm(t.list)?t.list:void 0,o=typeof t.dataset==`string`?e.datasetObject.get(t.dataset):void 0;return r(t.object)??r(t.objectName)??r(t.targetObject)??i(t.data,`object`)??i(t.config,`objectName`)??i(t.config,`object`)??(a?i(a.data,`object`):void 0)??r(t.name)??o??(Array.isArray(t.nodes)?t.nodes.map(e=>Vm(e)?i(e.config,`objectName`)??i(e.config,`object`):void 0).find(e=>e!==void 0):void 0)??n}function oh(e,t,n,r,i,a,o){if(t==null)return;if(typeof t==`function`){ih(e,Function.prototype.toString.call(t),n,r,i,a,o);return}if(typeof t==`string`){ih(e,t,n,r,i,a,o);return}if(typeof t!=`object`)return;if(Array.isArray(t)){for(let s=0;s<t.length;s++)oh(e,t[s],n,r,`${i}[${s}]`,a,o);return}let s=t,c=ah(e,s,n);for(let[t,n]of Object.entries(s)){let s=`${i}.${t}`,l=[...a,t];if(e.objectsByField.has(t)&&(Ym.has(o)||Xm.has(o))){if(e.declares(c,t)){let n=Xm.has(o)?`carrier`:rh(r,l,o);e.record(c,t,{root:r,path:s,kind:n})}else e.unresolved+=1}oh(e,n,e.isObject(t)?t:c,r,s,l,t)}}var sh=new Set([`name`,`label`,`type`,`reference`]);function ch(e,t,n,r,i){for(let[i,a]of Object.entries(t))i!==`fields`&&i!==`name`&&oh(e,a,n,`objects`,`${r}.${i}`,[i],i);for(let{rec:r,path:a}of D(t.fields,i)){let t=Hm(r.reference),i=Hm(r.displayField);t&&i&&e.declares(t,i)&&e.record(t,i,{root:`objects`,path:`${a}.displayField`,kind:`display`});for(let[t,i]of Object.entries(r))sh.has(t)||t===`displayField`||oh(e,i,n,`objects`,`${a}.${t}`,[t],t)}}function lh(e,t){let n={};for(let{rec:e}of t){let t=Hm(e.name);t&&(n[t]=e)}return{nameField:Hm(e.nameField),displayNameField:Hm(e.displayNameField),fields:n}}function uh(e){return e.join(`, `)}function dh(e){let t=[];if(!Vm(e)||!Um.some(t=>t!==`objects`&&w(e[t]).length>0))return t;let n=new nh,r=[],i=D(e.objects,`objects`);for(let{rec:e,path:t}of i){let i=Hm(e.name);if(!i||!e.fields||typeof e.fields!=`object`)continue;let a=D(e.fields,`${t}.fields`),o=xt(e),s=De(lh(e,a));for(let{rec:e,path:t}of a){let a=Hm(e.name);if(!a)continue;n.declare(i,a);let c=o.has(a)||a===s||e.type===`master_detail`;r.push({object:i,field:a,path:t,exempt:c})}}if(r.length===0)return t;for(let t of w(e.datasets)){let e=Hm(t.name),r=Hm(t.object);e&&r&&n.datasetObject.set(e,r)}for(let{rec:e,path:t}of i){let r=Hm(e.name);r&&n.fieldsByObject.has(r)&&ch(n,e,r,t,`${t}.fields`)}for(let t of[...Um,...Wm])t!==`objects`&&oh(n,e[t],void 0,t,t,[],t);let a=[...Um,...Wm];for(let{object:e,field:i,path:o,exempt:s}of r){if(s)continue;let r=n.sites.get(`${e}.${i}`)??[];if(r.some(e=>e.kind!==`carrier`))continue;let c=r.map(e=>e.path),l=c.length>0?`carrier-only`:`inert`,u=[...n.objectsByField.get(i)??[]].filter(t=>t!==e),d=l===`carrier-only`?`Verdict: carrier-only \u2014 ${c.length} carrier site(s) name it without reading it, and a removal must clean each: ${uh(c)}.`:`Verdict: inert — no site of any kind names it.`,f=u.length>0?` The same name is declared on ${u.map(e=>`"${e}"`).join(`, `)}; verdicts are per object, so a consumer there does not cover this declaration.`:``;t.push({severity:`warning`,rule:Bm,where:`object "${e}" \xB7 field "${i}"`,path:o,message:`field "${i}" on object "${e}" is declared but nothing in this stack reads or displays it: no view column, form section, page binding, flow node, dataset, widget, formula, validation, hook or action names it. A translation label, a seed value, an import mapping, a permission grant or a flow that only WRITES it is a carrier, not a consumer. ${d}${f}`,hint:`Give "${i}" a consumer \u2014 a view column, a form section, a page binding, a formula, a validation, a flow node, a dataset dimension \u2014 or remove the declaration`+(c.length>0?` together with its ${c.length} carrier site(s) listed above`:``)+`. Ignore this if the field is read only by an API client, by a hook or package this stack does not carry, or by a Studio-authored view. Roots scanned: ${Um.join(`, `)} (consumers) \xB7 ${Wm.join(`, `)} (carriers); test fixtures are never scanned.`,object:e,field:i,verdict:l,carriers:c,rootsScanned:a})}return t}var fh=`screen`,ph=`translation-target-unknown`,mh=`translation-option-key-unknown`;function G(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function K(e){return typeof e==`string`&&e.length>0?e:void 0}function hh(e,t){let n=K(e.name);n&&t.add(n),G(e.then)&&hh(e.then,t),G(e.otherwise)&&hh(e.otherwise,t)}function q(e,t){let n=[...t],r=n.find(t=>t.endsWith(`_${e}`)||t.startsWith(`${e}_`));return r?` Did you mean "${r}"?`:T(e,n)}function J(e,t=12){let n=[...e].sort();if(n.length===0)return``;let r=n.slice(0,t).join(`, `);return n.length>t?`${r}, \u2026 (${n.length} total)`:r}var gh=new Set([...bt,`_id`,`name`,`space`]);function _h(){return{fields:new Map,views:new Set,actions:new Map,sections:new Set,validations:new Set,tabs:new Set}}function vh(e,t){let n=tc(e),r=e=>tc(e)??n,i=(e,n)=>{e&&n&&t(e).views.add(n)},a=(e,n)=>{if(n)for(let r of w(e.sections)){let e=K(r.name);e&&t(n).sections.add(e)}},o=G(e.list)?r(e.list):void 0;G(e.list)&&i(o,bh(o,e)),i(n??o,K(e.name));let s=xh(e);for(let t of[`listViews`,`formViews`]){let n=e[t];if(!G(n))continue;let c=t===`listViews`?s.list:s.form,l=0;for(let e of Object.values(n)){if(!e||typeof e!=`object`)continue;let t=c[l++];if(!G(e))continue;let n=r(e)??o;i(n,t),a(e,n)}}G(e.form)&&a(e.form,r(e.form)??o),a(e,n??o)}function yh(e,t){let n=G(e.interfaceConfig)?e.interfaceConfig:void 0;if(!n)return;let r=G(n.userFilters)?n.userFilters:void 0;if(!r)return;let i=K(n.source)??K(e.object);if(i)for(let e of w(r.tabs)){let n=K(e.name);n&&t(i).tabs.add(n)}}function bh(e,t){if(!e||!G(t.list))return;let n=ve(e,t).find(e=>e.viewKind===`list`&&e.isDefault);if(!n)return;let r=`${e}.`;return n.name.startsWith(r)?n.name.slice(r.length):n.name}function xh(e){let t=`probe`,n=`${t}.`,r=e=>e.startsWith(n)?e.slice(n.length):e,i=e=>G(e)?Object.values(e).filter(e=>!!e&&typeof e==`object`).length:0,a=i(e.listViews),o=i(e.formViews);if(!a&&!o)return{list:[],form:[]};let s=ve(t,e),c=(e,t)=>s.filter(t=>t.viewKind===e).slice(0,t).map(e=>r(e.name));return{list:c(`list`,a),form:c(`form`,o)}}function Sh(e){let t=e.options,n=new Set,r=new Map;if(Array.isArray(t))for(let e of t){if(typeof e==`string`){n.add(e);continue}if(!G(e))continue;let t=K(e.value);if(!t)continue;n.add(t);let i=K(e.label);i&&r.set(i.toLowerCase(),t)}else if(G(t))for(let[e,i]of Object.entries(t))n.add(e),typeof i==`string`&&i.length>0&&r.set(i.toLowerCase(),e);else return;return n.size>0?{values:n,byLabel:r}:void 0}function Ch(e){let t=new Map,n=e=>{let n=t.get(e);return n||(n=_h(),t.set(e,n)),n};for(let t of w(e.objects)){let e=K(t.name);if(!e)continue;let r=n(e);for(let e of w(t.fields)){let t=K(e.name);t&&r.fields.set(t,e)}for(let e of w(t.actions)){let t=K(e.name);t&&r.actions.set(t,e)}for(let r of w(t.views))vh({...r,object:K(r.object)??e},n);vh({object:e,listViews:t.listViews},n);for(let e of w(t.fieldGroups)){let t=K(e.key)??K(e.name);t&&r.sections.add(t)}for(let e of w(t.validations))hh(e,r.validations)}for(let t of w(e.views))vh(t,n);let r=w(e.pages);for(let e=0;e<r.length;e++){yh(r[e],n);for(let t of Ro(r[e],`pages[${e}]`)){if(!t.objectName)continue;let e=G(t.component.properties)?t.component.properties:void 0;if(e)for(let r of w(e.sections)){let e=K(r.name);e&&n(t.objectName).sections.add(e)}}}let i=new Map,a=new Map;for(let t of w(e.actions)){let e=K(t.name);if(!e)continue;let r=K(t.objectName)??K(t.object);r?(n(r).actions.set(e,t),a.set(e,r)):i.set(e,t)}for(let[e,n]of t)for(let t of n.actions.keys())a.has(t)||a.set(t,e);let o=new Map;for(let t of w(e.apps)){let e=K(t.name);if(!e)continue;let n=o.get(e)??new Set,r=e=>{for(let t of w(e)){let e=K(t.id);e&&n.add(e),t.children&&r(t.children)}};r(t.navigation);for(let e of w(t.areas)){let t=K(e.id);t&&n.add(t),r(e.navigation)}o.set(e,n)}let s=new Map;for(let t of w(e.dashboards)){let e=K(t.name);if(!e)continue;let n=new Set;for(let e of w(t.widgets)){let t=K(e.id)??K(e.name);t&&n.add(t)}let r=new Set,i=[...w(G(t.header)?t.header.actions:void 0),...w(t.actions)];for(let e of i){let t=K(e.actionUrl)??K(e.url)??K(e.name);t&&r.add(t)}s.set(e,{widgets:n,actions:r})}let c=new Map;for(let t of w(e.flows)){let e=K(t.name);if(!e)continue;let n=new Map,r=new Map;for(let{node:e}of wi(t,``)){let t=K(e.id);if(!t)continue;let i=K(e.type);if(i!==fh){i&&!r.has(t)&&r.set(t,i);continue}let a=G(e.config)?e.config:void 0,o=new Set;for(let e of w(a?.fields)){let t=K(e.name);t&&o.add(t)}n.set(t,{fields:o,objectName:K(a?.objectName)})}c.set(e,{screens:n,otherNodes:r})}return{objects:t,apps:o,dashboards:s,flows:c,globalActions:i,actionOwners:a}}function wh(e,t){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(t)?`translations[${e}].${t}`:`translations[${e}]["${t}"]`}function Th(e){let t=[];if(!G(e))return t;let n=Array.isArray(e.translations)?e.translations:[];if(n.length===0)return t;let r=Ch(e),i=(e,n,r,i)=>{t.push({severity:`warning`,rule:ph,where:e,path:n,message:r,hint:i})};for(let e=0;e<n.length;e++){let a=n[e];if(G(a))for(let[n,o]of Object.entries(a)){if(!G(o))continue;let a=wh(e,n),s=`locale "${n}"`;for(let[e,n]of Object.entries(Y(o.objects))){if(!G(n))continue;let o=`${a}.objects.${e}`,c=r.objects.get(e);if(!c){if(Qe(e))continue;i(`${s} \xB7 object "${e}"`,o,y(e)?`Translations are keyed to "${e}", which carries a platform namespace prefix but is registered by no platform package, official plugin, or cloud runtime object \u2014 and this stack does not define it either. Nothing resolves these keys.`+q(e,r.objects.keys()):`Translations are keyed to "${e}", which no object in this stack defines. The resolver looks up keys derived from the metadata, so this whole subtree is dead weight \u2014 every label it carries renders untranslated.`+q(e,r.objects.keys()),`Rename the key to the object it was written for, drop it, or ignore this if the object is contributed by another installed package.`+(r.objects.size>0?` Defined objects: ${J(r.objects.keys())}.`:``));continue}for(let[r,a]of Object.entries(Y(n.fields))){let n=`${o}.fields.${r}`,l=c.fields.get(r);if(!l){if(gh.has(r))continue;i(`${s} \xB7 object "${e}" \xB7 field "${r}"`,n,`Translations are keyed to field "${r}", which object "${e}" does not declare. The label renders untranslated in this locale \u2014 and because every neighbouring field DOES resolve, the hole reads as a styling quirk rather than a missing translation.`+q(r,c.fields.keys()),`Point the key at a declared field, or drop it if the field was removed or renamed.`+(c.fields.size>0?` Declared fields: ${J(c.fields.keys())}.`:``));continue}G(a)&&Eh(t,{optionMap:a.options,field:l,fieldName:r,objectName:e,path:`${n}.options`,where:`${s} \xB7 object "${e}" \xB7 field "${r}"`})}for(let t of Object.keys(Y(n._views)))c.views.has(t)||i(`${s} \xB7 object "${e}" \xB7 view "${t}"`,`${o}._views.${t}`,`Translations are keyed to view "${t}", which no view of object "${e}" declares. The view tab keeps its source-locale label.`+q(t,c.views),"Match the key to the view's `name` (not its label), or drop it."+(c.views.size>0?` Declared views: ${J(c.views)}.`:``));for(let t of Object.keys(Y(n._sections)))c.sections.has(t)||i(`${s} \xB7 object "${e}" \xB7 section "${t}"`,`${o}._sections.${t}`,`Translations are keyed to section "${t}", which nothing on object "${e}" declares \u2014 no \`fieldGroups[].key\`, no named form-view section, no named \`record:details\` section. The section heading stays in the source locale.`+q(t,c.sections),"Sections are translatable only through a STABLE NAME: give the group/section a `key`/`name` and use it here, or drop the translation."+(c.sections.size>0?` Declared sections: ${J(c.sections)}.`:` Object "${e}" declares no named section at all.`));for(let t of Object.keys(Y(n._tabs)))c.tabs.has(t)||i(`${s} \xB7 object "${e}" \xB7 tab "${t}"`,`${o}._tabs.${t}`,`Translations are keyed to filter-preset tab "${t}", which no page over object "${e}" declares in \`interfaceConfig.userFilters.tabs\`. The tab keeps its source-locale label \u2014 above a grid whose every column resolves, so the hole reads as a styling quirk rather than a missing translation.`+q(t,c.tabs),"Match the key to the tab's `name` (not its label), or drop it if the preset was renamed or removed."+(c.tabs.size>0?` Declared tabs: ${J(c.tabs)}.`:` No page over "${e}" declares a filter-preset tab bar at all. Note only a page's \`interfaceConfig.userFilters.tabs\` is resolvable \u2014 a list view's own \`tabs\` has no renderer, so nothing reads a key written for one.`));for(let t of Object.keys(Y(n._validations)))c.validations.has(t)||i(`${s} \xB7 object "${e}" \xB7 validation "${t}"`,`${o}._validations.${t}`,`Translations are keyed to validation rule "${t}", which object "${e}" does not declare in \`validations[]\`. The rule's authored \`message\` keeps its source locale in every refusal.`+q(t,c.validations),"Match the key to the rule's `name`, or drop it if the rule was renamed or removed."+(c.validations.size>0?` Declared rules: ${J(c.validations)}.`:` Object "${e}" declares no named validation rules.`));for(let[r,a]of Object.entries(Y(n._actions))){let n=`${o}._actions.${r}`,l=c.actions.get(r);if(!l){i(`${s} \xB7 object "${e}" \xB7 action "${r}"`,n,`Translations are keyed to action "${r}", which is defined by neither object "${e}"'s \`actions\` nor a \`stack.actions\` entry bound to it. The button keeps its source-locale label.`+q(r,c.actions.keys()),`Match the key to a defined action name, move it under the object that owns the action, or drop it.`+(c.actions.size>0?` Actions on this object: ${J(c.actions.keys())}.`:``));continue}Dh(t,{rawAction:a,action:l,path:n,where:`${s} \xB7 object "${e}" \xB7 action "${r}"`,subject:`action "${r}"`})}}for(let[e,n]of Object.entries(Y(o.globalActions))){let o=`${a}.globalActions.${e}`,c=r.globalActions.get(e);if(!c){let t=r.actionOwners.get(e);i(`${s} \xB7 global action "${e}"`,o,t?`Action "${e}" is bound to object "${t}", so the resolver looks it up under \`objects.${t}._actions.${e}\` \u2014 never under \`globalActions\`, which is only consulted for object-less actions. This key is never read.`:`Translations are keyed to global action "${e}", which no object-less action in this stack defines. The button keeps its source-locale label.`+q(e,r.globalActions.keys()),t?`Move these keys under \`objects.${t}._actions.${e}\`.`:`Match the key to an object-less action's name, or drop it.`+(r.globalActions.size>0?` Object-less actions: ${J(r.globalActions.keys())}.`:``));continue}Dh(t,{rawAction:n,action:c,path:o,where:`${s} \xB7 global action "${e}"`,subject:`action "${e}"`})}for(let[e,t]of Object.entries(Y(o.apps))){let n=`${a}.apps.${e}`,o=r.apps.get(e);if(!o){i(`${s} \xB7 app "${e}"`,n,`Translations are keyed to app "${e}", which this stack does not define. The app launcher shows the source-locale label.`+q(e,r.apps.keys()),"Match the key to an app's `name`, or drop it."+(r.apps.size>0?` Defined apps: ${J(r.apps.keys())}.`:``));continue}if(G(t))for(let r of Object.keys(Y(t.navigation)))o.has(r)||i(`${s} \xB7 app "${e}" \xB7 navigation "${r}"`,`${n}.navigation.${r}`,`Translations are keyed to navigation item "${r}", which app "${e}" does not declare. The menu entry keeps its source-locale label.`+q(r,o),"Match the key to the navigation item's `id`, or drop it."+(o.size>0?` Declared navigation ids: ${J(o)}.`:``))}for(let[e,t]of Object.entries(Y(o.dashboards))){let n=`${a}.dashboards.${e}`,o=r.dashboards.get(e);if(!o){i(`${s} \xB7 dashboard "${e}"`,n,`Translations are keyed to dashboard "${e}", which this stack does not define. The dashboard title stays in the source locale.`+q(e,r.dashboards.keys()),"Match the key to a dashboard's `name`, or drop it."+(r.dashboards.size>0?` Defined dashboards: ${J(r.dashboards.keys())}.`:``));continue}if(G(t)){for(let r of Object.keys(Y(t.widgets)))o.widgets.has(r)||i(`${s} \xB7 dashboard "${e}" \xB7 widget "${r}"`,`${n}.widgets.${r}`,`Translations are keyed to widget "${r}", which dashboard "${e}" does not declare. The widget title stays in the source locale.`+q(r,o.widgets),"Match the key to the widget's `id`, or drop it."+(o.widgets.size>0?` Declared widget ids: ${J(o.widgets)}.`:``));for(let r of Object.keys(Y(t.actions)))o.actions.has(r)||i(`${s} \xB7 dashboard "${e}" \xB7 action "${r}"`,`${n}.actions.${r}`,`Translations are keyed to header action "${r}", which dashboard "${e}" does not declare. The button keeps its source-locale label.`+q(r,o.actions),"Header-action translations are keyed by the action's `actionUrl`, not its label."+(o.actions.size>0?` Declared header actions: ${J(o.actions)}.`:``))}}for(let[e,t]of Object.entries(Y(o.flows))){let n=`${a}.flows.${e}`,o=r.flows.get(e);if(!o){i(`${s} \xB7 flow "${e}"`,n,`Translations are keyed to flow "${e}", which this stack does not define. The wizard renders its source-locale label and headings.`+q(e,r.flows.keys()),"Match the key to a flow's `name` (the machine name, not its label), or drop it."+(r.flows.size>0?` Defined flows: ${J(r.flows.keys())}.`:``));continue}if(G(t))for(let[r,a]of Object.entries(Y(t.screens))){let t=`${n}.screens.${r}`,c=o.screens.get(r);if(!c){let n=o.otherNodes.get(r);i(`${s} \xB7 flow "${e}" \xB7 screen "${r}"`,t,n?`Translations are keyed to screen "${r}", which flow "${e}" declares as a \`${n}\` node, not a \`screen\`. Only screen nodes render a heading and fields for a user to read, so nothing resolves these keys.`:`Translations are keyed to screen "${r}", which flow "${e}" declares no screen node for. The wizard step keeps its source-locale heading.`+q(r,o.screens.keys()),"Screen translations are keyed by the node's `id` (the client's `ScreenSpec.nodeId`), not its `label`."+(o.screens.size>0?` Declared screen node ids: ${J(o.screens.keys())}.`:` Flow "${e}" declares no \`type: 'screen'\` node at all.`));continue}if(G(a))for(let n of Object.keys(Y(a.fields))){if(c.fields.has(n))continue;let a=c.fields.size===0?c.objectName:void 0;i(`${s} \xB7 flow "${e}" \xB7 screen "${r}" \xB7 field "${n}"`,`${t}.fields.${n}`,a?`Translations are keyed to screen field "${n}", but screen "${r}" is an OBJECT-FORM screen (\`config.objectName: "${a}"\`) \u2014 it renders that object's own create/edit form, so its input labels come from \`objects.${a}.fields.*\` and nothing reads a field key here.`:`Translations are keyed to screen field "${n}", which screen "${r}" of flow "${e}" does not declare. The input keeps its source-locale label while every neighbouring field on the same screen resolves.`+q(n,c.fields),a?`Move this copy under \`objects.${a}.fields.${n}\`, or drop it.`:"Match the key to a `config.fields[].name` on that screen, or drop it."+(c.fields.size>0?` Declared screen field names: ${J(c.fields)}.`:` Screen "${r}" declares no \`config.fields\` at all.`))}}}}}return t}function Y(e){return G(e)?e:{}}function Eh(e,t){let n=Object.keys(Y(t.optionMap));if(n.length===0)return;let r=Sh(t.field);if(!r){e.push({severity:`warning`,rule:mh,where:t.where,path:t.path,message:`Option translations are keyed under field "${t.fieldName}" of object "${t.objectName}", which declares no \`options\` at all (field type "${K(t.field.type)??`unknown`}"). Nothing reads this map.`,hint:`Declare the options on the field, move the translations to the field that owns them, or drop them.`});return}for(let i of n){if(r.values.has(i))continue;let n=r.byLabel.get(i.toLowerCase());e.push({severity:`warning`,rule:mh,where:t.where,path:`${t.path}.${i}`,message:n?`Option translation is keyed by the DISPLAY LABEL "${i}" instead of the stored value "${n}". The resolver looks the option up by value, so this entry is never found and the option renders with its source-locale label.`:`Option translation is keyed by "${i}", which is not one of the values declared by field "${t.objectName}.${t.fieldName}". The option renders untranslated.`+q(i,r.values),hint:n?`Rename the key to "${n}".`:`Option keys are the stored \`value\`, not the label and not a variant spelling (\`direct_mail\`, not \`direct-mail\`). Declared values: ${J(r.values)}.`})}}function Dh(e,t){let n=Object.keys(Y(G(t.rawAction)?t.rawAction.params:void 0));if(n.length===0)return;let r=new Set;for(let e of w(t.action.params)){let t=K(e.name)??K(e.field);t&&r.add(t)}for(let i of n)r.has(i)||e.push({severity:`warning`,rule:ph,where:`${t.where} \xB7 param "${i}"`,path:`${t.path}.params.${i}`,message:`Translations are keyed to parameter "${i}", which ${t.subject} does not declare. The parameter's label and help text render untranslated in the action dialog.`+q(i,r),hint:"Match the key to a declared param `name`, or drop it."+(r.size>0?` Declared params: ${J(r)}.`:``)})}var Oh=`translation-section-name-missing`;function kh(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function Ah(e){return typeof e==`string`&&e.length>0?e:void 0}function jh(e){let t=Ah(e.name);return t?`view "${t}"`:``}function Mh(...e){return e.filter(e=>e.length>0).join(` · `)}function Nh(e,t,n,r){let i=tc(e),a=kh(e.list)?tc(e.list)??i:void 0;for(let o of nc(e,t))r.push({path:`${o.path}.sections`,surface:Mh(n,o.surface),objectName:tc(o.view)??i??a,sections:o.view.sections})}function Ph(e){let t=new Set,n=Array.isArray(e.translations)?e.translations:[];for(let e of n)if(kh(e)){for(let n of Object.values(e))if(kh(n)&&kh(n.objects))for(let[e,r]of Object.entries(n.objects))kh(r)&&t.add(e)}return t}function Fh(e){let t=e.toLowerCase().replace(/&/g,` and `).replace(/[^a-z0-9]+/g,`_`).replace(/^_+|_+$/g,``);return t.length>0?t:void 0}function Ih(e){let t=[];if(!kh(e))return t;let n=Ph(e);if(n.size===0)return t;let r=[];for(let{rec:t,path:n}of D(e.objects,`objects`)){let e=Ah(t.name);if(e){for(let{rec:i,path:a}of D(t.views,`${n}.views`))Nh({...i,object:Ah(i.object)??e},a,jh(i),r);kh(t.listViews)&&Nh({object:e,listViews:t.listViews},n,``,r)}}for(let{rec:t,path:n}of D(e.views,`views`))Nh(t,n,jh(t),r);for(let{rec:t,path:n}of D(e.pages,`pages`)){let e=Ah(t.name),i=e?`page "${e}"`:``;for(let e of Ro(t,n)){if(!e.objectName)continue;let t=kh(e.component.properties)?e.component.properties:void 0;if(!t)continue;let n=Ah(e.component.type)??`component`;r.push({path:`${e.path}.properties.sections`,surface:Mh(i,n),objectName:e.objectName,sections:t.sections})}}for(let e of r){let r=e.objectName;if(r&&n.has(r)&&Array.isArray(e.sections))for(let n=0;n<e.sections.length;n++){let i=e.sections[n];if(!kh(i)||Ah(i.name))continue;let a=Ah(i.label);if(!a)continue;let o=Fh(a);t.push({severity:`warning`,rule:Oh,where:Mh(`object "${r}"`,e.surface,`section "${a}"`),path:`${e.path}[${n}]`,message:`Section "${a}" declares a label but no \`name\`. Headings resolve through \`objects.${r}._sections.<name>.label\`, so a section with no name has no key a bundle can carry \u2014 this heading can never be translated and renders in the source locale in EVERY locale. Object "${r}" IS translated, which is what makes the hole invisible: every neighbouring label resolves and only the heading stays behind. The i18n coverage report cannot see it either \u2014 it walks \`sections[].name\`, and a nameless section contributes nothing to walk.`,hint:"Give the section a stable `name` (snake_case)"+(o?`, e.g. \`name: '${o}'\``:``)+`, then translate it as \`objects.${r}._sections.${o??`<name>`}.label\` in each locale bundle. The renderers look the heading up by name only \u2014 the name above is a suggestion to write down, never a key derived from the label, so renaming the heading later cannot break the lookup.`})}}return t}var Lh=`ai-skill-surface-mismatch`;function Rh(e){return typeof e==`string`&&e.length>0?e:void 0}function zh(e){return typeof e==`string`&&e.length>0?e:`ask`}function Bh(e){let t=[];if(!e||typeof e!=`object`)return t;let n=new Map;for(let t of w(e.skills)){let e=Rh(t.name);e&&n.set(e,t)}let r=w(e.agents);for(let e=0;e<r.length;e++){let i=r[e],a=Rh(i.name)??`#${e}`,o=zh(i.surface),s=Array.isArray(i.skills)?i.skills:[];for(let r=0;r<s.length;r++){let i=Rh(s[r]);if(!i)continue;let c=n.get(i);if(!c)continue;let l=zh(c.surface);l!==`both`&&l!==o&&t.push({severity:`error`,rule:Lh,where:`agent "${a}" \xB7 skills`,path:`agents[${e}].skills[${r}]`,message:`Agent "${a}" (surface: '${o}') references skill "${i}" (surface: '${l}') \u2014 incompatible affinity (ADR-0064 \xA73). The runtime refuses this binding with a load error, so chatting with this agent fails at request time even though the stack parses and validates cleanly.`,hint:`A skill may only attach to an agent whose surface it matches. Move "${i}" to a '${l}'-surface agent, change its \`surface\` to '${o}', or \u2014 only if it is a genuinely shared, read-only capability \u2014 declare \`surface: 'both'\`.`})}}return t}var Vh=`ai-skill-tool-unresolved`;function Hh(e){return typeof e==`string`&&e.length>0?e:void 0}function Uh(e,t){for(let n of ye)if(t.has(`${n}${e}`))return` Did you mean "${n}${e}"?`;return T(e,t)}var Wh=new Set([`script`,`api`,`flow`]),Gh=`update`;function Kh(e){let t=e.ai;if(!t||typeof t!=`object`)return!1;let n=t;if(n.exposed!==!0||!Hh(n.description))return!1;if(e.operation===Gh)return!0;let r=Hh(e.type);return!r||!Wh.has(r)?!1:r===`script`?!!(e.target||e.body):!!e.target}function qh(e){let t=new Set(ge);for(let n of w(e.tools)){let e=Hh(n.name);e&&t.add(e)}let n=e=>{for(let n of w(e)){let e=Hh(n.name);e&&Kh(n)&&t.add(`action_${e}`)}};n(e.actions);for(let t of w(e.objects))n(t.actions);return t}function Jh(e){let t=new Set,n=e=>{for(let n of w(e)){let e=Hh(n.name);e&&!Kh(n)&&t.add(e)}};n(e.actions);for(let t of w(e.objects))n(t.actions);return t}function Yh(e){let t=[];if(!e||typeof e!=`object`)return t;let n=qh(e),r=Jh(e),i=e=>{if(e.endsWith(`*`)){let t=e.slice(0,-1);for(let e of n)if(e.startsWith(t))return!0;return!1}return n.has(e)},a=w(e.skills);for(let e=0;e<a.length;e++){let o=a[e],s=Hh(o.name)??`#${e}`,c=Array.isArray(o.tools)?o.tools:[];for(let a=0;a<c.length;a++){let o=Hh(c[a]);if(!o||i(o))continue;let l=o.endsWith(`*`),u=!l&&o.startsWith(`action_`)&&r.has(o.slice(7))?o.slice(7):void 0;t.push({severity:`warning`,rule:Vh,where:`skill "${s}" \xB7 tools`,path:`skills[${e}].tools[${a}]`,message:l?`Skill "${s}" subscribes to tool family "${o}", which matches nothing this stack can resolve (no declared tool, no platform tool, and no AI-exposed declarative action materialises into it). The subscription contributes zero tools at runtime.`:u?`Skill "${s}" references tool "${o}", but the action "${u}" does not become an AI tool: the runtime materialises \`action_<name>\` only for an action that opts in with \`ai.exposed: true\` + \`ai.description\` (ADR-0011) AND has a headless path (type \`script\`/\`api\`/\`flow\` with a target or body \u2014 \`url\`/\`modal\`/\`form\` are UI-only). The reference is dropped at runtime, so the skill promises a capability the agent cannot call.`:`Skill "${s}" references tool "${o}", which resolves to nothing this stack can see: not a \`stack.tools\` record, not a platform-registered tool, and not a materialised action tool (\`action_<name>\`). The runtime silently drops the reference, so the skill's instructions claim a capability the agent does not have \u2014 the assistant will improvise or fail when asked to use it.`+Uh(o,n),hint:u?`Either opt "${u}" in \u2014 set \`ai: { exposed: true, description: '\u2026' }\` (\u226540 chars, LLM-facing) and give it a headless type \u2014 or drop the reference and have the skill's instructions recommend the UI action instead. A \`modal\`/\`form\`/\`url\` action stays human-driven by design; that is a legitimate answer, not a gap.`:`Back "${o}" with a real executable: declare a declarative action (or flow), opt it in with \`ai.exposed: true\` + \`ai.description\`, and reference its materialised tool (\`action_<name>\` \u2014 the ADR-0109 default path, no tool record needed); or reference a platform tool by its registered name; or remove the reference and the instructions that mention it. Ignore this only if a runtime plugin outside the platform registry provides "${o}". Family prefixes materialised by the runtime: ${ye.join(`, `)}.`})}}return t}var Xh=`agent-authoring-withdrawn`,Zh=`default-agent-outside-roster`,Qh=`default-agent-legacy-alias`;function $h(e){return typeof e==`string`&&e.length>0?e:void 0}var eg=[`ask`,`build`],tg=new Map([[`data_chat`,`ask`],[`metadata_assistant`,`build`]]),ng=new Set([...eg,...tg.keys()]);function rg(e){let t=[];if(!e||typeof e!=`object`)return t;let n=w(e.agents);for(let e=0;e<n.length;e++){let r=n[e],i=$h(r.name)??`#${e}`,a=ng.has(i),o=Array.isArray(r.skills)?r.skills.length:0;t.push({severity:`warning`,rule:Xh,where:`agent "${i}"`,path:`agents[${e}]`,message:a?`This stack declares an agent named "${i}", which is a PLATFORM agent id. The runtime serves its own record for that name and ignores this one \u2014 the declaration has no effect and will drift from the platform's definition.`:`This stack declares the agent "${i}", but tenant/app-package agents were withdrawn (ADR-0063 \xA72): the kernel ships exactly two agents (\`ask\`, \`build\`) and the surface the user is in binds one. The runtime filters this record out of the agent catalog and refuses to load it, so it never runs \u2014 it parses, validates, and ships as inert metadata.`,hint:a?`Remove the declaration; the platform owns "${i}". Extend it with skills instead.`:"Delete the agent and express its capability as skills. Everything an agent carried that a skill does not is persona text: move the useful parts of `instructions` into the skills' own instructions."+(o>0?` The ${o} skill${o===1?``:`s`} this agent references already carry the capability \u2014 they attach to the platform agent by \`surface\` affinity, so nothing is lost by dropping the persona.`:``)})}let r=eg.join(`, `),i=w(e.apps);for(let e=0;e<i.length;e++){let n=i[e],a=$h(n.defaultAgent);if(!a||eg.includes(a))continue;let o=$h(n.name)??`#${e}`,s=tg.get(a);if(s){t.push({severity:`warning`,rule:Qh,where:`app "${o}".defaultAgent`,path:`apps[${e}].defaultAgent`,message:`app "${o}" pins \`defaultAgent\` to "${a}", the RETIRED alias of the platform agent "${s}". It still resolves \u2014 the alias registry maps legacy names to canonical ones for old bookmarks and persisted \`agent_id\`s (ADR-0063 \xA72) \u2014 so nothing is broken at runtime; what is wrong is the spelling in the artifact. It is also the weaker pin: resolution depends on the owning package's in-process alias registration having run, which the canonical id does not.`,hint:`Write \`defaultAgent: '${s}'\`. The aliases are back-compat resolution, not authoring vocabulary \u2014 always author the canonical id (${r}).`});continue}t.push({severity:`warning`,rule:Zh,where:`app "${o}".defaultAgent`,path:`apps[${e}].defaultAgent`,message:`app "${o}" pins \`defaultAgent\` to "${a}", which is not a platform agent (${r}). The kernel ships exactly two agents (ADR-0063 \xA72) and resolves this key against them and their legacy aliases only \u2014 an unrecognized name is not rejected, it silently falls back to the platform default at runtime, so the pin has no effect and the value drifts from what actually serves the app.`,hint:`Set \`defaultAgent\` to one of the platform agent names: ${r}. If the goal is a dedicated persona or capability, express it as skills instead \u2014 they attach to "ask" / "build" by surface affinity, not as a custom \`defaultAgent\` value.`})}return t}var ig=`flow-node-write-unknown-field`,ag=`flow-node-write-unprovisioned-anchor`,og=[`update_record`,`create_record`],sg=[],cg=e=>!!e&&typeof e==`object`&&!Array.isArray(e);function lg(e){let t=e.objectName??e.object;if(!(typeof t!=`string`||t.includes(`{`)))return t||void 0}var ug=new Set(og);function dg(e){let t=[];if(!cg(e))return t;let n=w(e.flows);if(n.length===0)return t;let r=null,i=null;return n.forEach((n,a)=>{let o=typeof n.name==`string`&&n.name?n.name:`#${a}`;wi(n,`flows[${a}]`).forEach(({node:n,path:a,regionTrail:s},c)=>{if(typeof n.type!=`string`||!ug.has(n.type))return;let l=cg(n.config)?n.config:void 0;if(!l)return;let u=l.fields;if(!cg(u))return;let d=Object.keys(u);if(d.length===0)return;let f=lg(l);if(!f)return;r??=la(e),i??=wt(e);let p=ua(r,f);if(!p)return;let m=bi(n,c),h=s?`${s} \u203A node "${m}"`:`node "${m}"`;for(let e of d)if(!p.has(e)){if(oa.has(e)){if(!i.get(f)?.has(e))continue;t.push({severity:`warning`,rule:ag,where:`flow "${o}" \u203A ${h}`,path:`${a}.config.fields.${e}`,message:`${n.type} writes '${e}', and ${Tt(f,e)} \u2014 `+sa(),hint:Et(f,e)});continue}e.includes(`.`)||t.push({severity:`error`,rule:ig,where:`flow "${o}" \u203A ${h}`,path:`${a}.config.fields.${e}`,message:`${n.type} writes '${e}', but object '${f}' declares no such field. The node hands its fields map to the engine as an ordinary caller payload, so the declared-field door REFUSES the whole write \u2014 INVALID_FIELD / 400, identically on every datasource, before any statement is built. The correctly named fields in this same payload never land either${n.type===`create_record`?` and the record is never created at all`:``}, and the step fails the run.`,hint:fg(e,[...p])})}})}),t}function fg(e,t){let n=x(g(e,[...t,...oa]));return(n?`${n} `:``)+`Fix the field name, or declare '${e}' on the object. This gates the build rather than warning: the key is literal and so is the object, so unlike the hook/action body rules there is nothing here that could have been mis-extracted.`}var pg=[`flow`],mg=[{name:`validateObjectReferences`,run:pf},{name:`validateSearchableFields`,runtimeTypes:[`flow`,`view`,`object`],run:Mo},{name:`validateSortableFields`,runtimeTypes:[`flow`,`view`],run:Rf},{name:`validateListViewFieldRefs`,runtimeTypes:[`flow`,`view`,`object`],run:Xf},{name:`validateObjectFieldRefs`,runtimeTypes:[`flow`,`object`],run:tp},{name:`validateActionNameRefs`,run:ap},{name:`validatePageFieldBindings`,run:ns},{name:`validatePageVisualizationBindings`,run:Dp},{name:`validateChartBindings`,run:Qp},{name:`validateDatasetReferences`,run:om},{name:`validateNavAccess`,run:zm},{name:`validateNavTargetRefs`,run:bf},{name:`validateViewPageRefs`,runtimeTypes:[`flow`,`view`],run:Ef},{name:`validateNavObjectServability`,run:jf},{name:`validateTranslationReferences`,run:Th},{name:`validateTranslatableSections`,run:Ih},{name:`validateFlowTemplatePaths`,run:Bi},{name:`validateAiSurfaceAffinity`,run:Bh},{name:`validateAiToolReferences`,run:Yh},{name:`validateAiAgentAuthoring`,run:rg},{name:`validateHookBodyWrites`,run:pa},{name:`validateActionBodyWrites`,run:Va},{name:`validateFlowNodeWrites`,run:dg},{name:`validateReadonlyFlowWrites`,run:Ji},{name:`validateReadonlyHookWrites`,run:Ea},{name:`validateReadonlyActionWrites`,run:Za},{name:`validateReactPageProps`,run:Bs}];function hg(e,t){let n=[],r=t?.runtimeWriteType;for(let t of mg)(r===void 0||(t.runtimeTypes??pg).includes(r))&&n.push(...t.run(e));return n}function gg(e){return typeof e==`string`?e:e&&typeof e==`object`&&typeof e.source==`string`?e.source:``}var _g=`daysFromNow|daysAgo|today|now|date|datetime`,vg=RegExp(`\\b(?:${_g})\\s*\\(`),yg=RegExp(`(?:(?:${_g})\\s*\\([^)]*\\)\\s*(?:==|!=))|(?:(?:==|!=)\\s*(?:${_g})\\s*\\()`),bg=`flow-time-relative-antipattern`,xg=`flow-date-equality-filter`,Sg=`flow-phantom-aggregation`,Cg=`flow-double-brace-interpolation`,wg=`flow-bare-dollar-reference`,Tg=`flow-approval-revise-dead-end`,Eg=`flow-approval-revise-unmarked-backedge`,Dg=`flow-approval-revise-disabled`,Og=`flow-approval-revise-target-not-service-owned`,kg=`flow-runas-unscoped`,Ag=`flow-error-label-not-fault`,jg=`flow-branch-label-unmatched`,Mg=`flow-decision-unconditional-branch`,Ng=`flow-default-edge-with-condition`,Pg=`flow-multiple-default-edges`,Fg=`flow-inert-node-condition`,Ig=`flow-multi-write-unfiltered`,Lg=`flow-loop-body-uncontained`,Rg=`flow-try-catch-without-catch`,zg=new Set([`decision`,`assignment`,`loop`,`parallel`,`try_catch`,`create_record`,`update_record`,`delete_record`,`get_record`,`http`,`notify`,`script`,`screen`,`wait`,`subflow`,`map`,`connector_action`,`approval`,`end`]),Bg=new Set([`get_record`,`create_record`,`update_record`,`delete_record`]),Vg=new Set([`get_record`,`create_record`,`update_record`,`delete_record`,`http`,`notify`,`connector_action`,`script`,`subflow`,`map`,He]),Hg=`try_catch`,Ug=`loop`,Wg="`runAs:'user'` (the default when none is declared)";function Gg(e,t){for(let n of me({nodes:e,edges:t}))for(let e of w(n.nodes))if(Bg.has(typeof e.type==`string`?e.type:``))return{node:e,scope:n.scope};return null}var Kg=new Map([[`delete_record`,{verb:`deleted`,engineCall:`driver.deleteMany`,dispatchNote:"the engine's delete-dispatch case-set lists `multi with no predicate at all` as a legal `multi` call"}],[`update_record`,{verb:`overwritten`,engineCall:`driver.updateMany`,dispatchNote:"the engine takes its bulk branch on `options.multi` alone (`Update requires an ID or options.multi=true` is refused only when the declaration is absent)"}]]),qg=new Set([`error`,`fault`,`failure`,`failed`,`catch`,`on_error`,`onerror`,`on error`]),Jg=new Set([`decision`,`approval`,`screen`,`try_catch`]);function Yg(e,t){return e.type===`schedule`||typeof t.triggerType==`string`&&t.triggerType===`schedule`||t.schedule!=null}function Xg(e,t){return Yg(e,t)?`schedule`:t.timeRelative!=null||typeof t.triggerType==`string`&&t.triggerType===`time_relative`?`time-relative`:e.type===`api`||typeof t.triggerType==`string`&&t.triggerType===`api`?`api`:null}var Zg=new Set([`aggregations`,`aggregate`,`groupBy`,`rollup`,`having`]);function Qg(e){if(e&&typeof e==`object`&&e.dialect===`cel`){let t=e.source;if(typeof t==`string`&&vg.test(t))return t}return null}var $g=new Set([`$gte`,`$gt`,`$lte`,`$lt`,`$ne`]);function e_(e,t,n){if(e&&typeof e==`object`&&!Array.isArray(e))for(let[r,i]of Object.entries(e)){if(r===`$or`||r===`$and`){if(Array.isArray(i))for(let e of i)e_(e,t,n);continue}let e=Qg(i),a=e?{op:`==`,src:e}:null;if(!a&&i&&typeof i==`object`&&i.dialect!==`cel`){for(let[e,t]of Object.entries(i))if(!$g.has(e)){if(e===`$eq`){let e=Qg(t);if(e){a={op:`$eq`,src:e};break}}else if(e===`$in`&&Array.isArray(t)){for(let e of t){let t=Qg(e);if(t){a={op:`$in`,src:t};break}}if(a)break}}}a&&n.push({where:t,message:`filter matches \`${r}\` by ${a.op} against a time value (\`${a.src}\`) \u2014 a date field carries a time component, so exact equality against \`${a.src}\` (re-computed each run) silently matches nothing.`,hint:`Use a one-day window instead: \`${r}: { $gte: daysFromNow(N), $lt: daysFromNow(N+1) }\` (wrap multiple tiers in \`$or\`). The abutting windows tile the timeline so each row matches exactly once. (#1874)`,rule:xg})}}var t_=/\{\{\s*[\w$][\w$.\s]*\}\}/,n_=/(?:^|[^{])\$[A-Za-z_]\w*\.[A-Za-z_]/,r_=new Set([`condition`,`expression`,`conditions`]);function i_(e,t,n){if(!(t&&r_.has(t))){if(typeof e==`string`){n.push(e);return}if(Array.isArray(e)){for(let r of e)i_(r,t,n);return}if(e&&typeof e==`object`)for(let[t,r]of Object.entries(e))i_(r,t,n)}}function a_(e){return typeof e.label==`string`?e.label.trim().toLowerCase():``}function o_(e,t,n,r){let i=new Map;for(let e of t)typeof e.id==`string`&&i.set(e.id,typeof e.type==`string`?e.type:``);for(let t of n){let n=typeof t.label==`string`?t.label.trim().toLowerCase():``;if(!qg.has(n)||t.type===`fault`||t.condition)continue;let a=typeof t.source==`string`?t.source:``;Jg.has(i.get(a)??``)||r.push({where:`${e} \xB7 edge '${a}' \u2192 '${String(t.target)}'`,message:`edge is labelled '${String(t.label)}' but its type is '${String(t.type??`default`)}', not 'fault' \u2014 so it is an ORDINARY out-edge. Unconditional out-edges all run in parallel, so '${String(t.target)}' executes on every SUCCESSFUL run of '${a}' and never on a failure. The error path the label describes does not exist, and the run still aborts when '${a}' fails.`,hint:"Add `type: 'fault'` to this edge. Only runtime failures route — a guard refusal (a filter token that resolved to nothing, a missing required config key, an unscoped run) stays fatal by design and must be fixed in the metadata, not handled. (#3863)",rule:Ag})}}function s_(e,t,n,r){let i=new Map;for(let e of n){if(e.type===`fault`)continue;let t=typeof e.source==`string`?e.source:``;t&&(i.has(t)||i.set(t,[]),i.get(t).push(e))}for(let[t,n]of i){for(let i of n)i.isDefault===!0&&i.condition&&r.push({where:`${e} \xB7 edge '${t}' \u2192 '${String(i.target)}'`,message:'edge sets `isDefault: true` AND a `condition` — contradictory. `isDefault` means "take this edge when NO sibling condition matched"; a condition makes it an ordinary guarded branch. The condition wins and the default marker routes nothing.',hint:'Drop one: keep `condition` for a guarded branch, or drop it and keep `isDefault: true` for the "otherwise" path. (#4414)',rule:Ng,severity:`error`});let i=n.filter(e=>e.isDefault===!0&&!e.condition);i.length>1&&r.push({where:`${e} \xB7 node '${t}'`,message:`${i.length} out-edges are marked \`isDefault: true\` (${i.map(e=>`'${String(e.target)}'`).join(`, `)}) \u2014 a node has at most ONE default path. All of them are traversed together when no condition matches, which is a parallel fan-out, not an "otherwise".`,hint:"Keep `isDefault: true` on the single fallback edge and give the others a `condition` (or leave them unconditional if the fan-out really is intended). (#4414)",rule:Pg})}for(let n of t){let t=typeof n.type==`string`?n.type:``;if(!zg.has(t))continue;let i=n.config??{};i.condition!=null&&gg(i.condition).trim()!==``&&r.push({where:`${e} \xB7 node '${String(n.id)}' (${t})`,message:"`config.condition` is set but nothing reads it — the key is the trigger gate on a `start` node and is ignored on every other node type, so this predicate never gates anything. (It is still parse-validated at registration, which is why a malformed one is caught and an inert one is not.)",hint:t===`decision`?"Branching lives on the OUT-EDGES: give each branch its own `condition` and mark the fallback `isDefault: true`. If the edges already carry the predicate, delete this copy. (#4414)":"Delete it, or move the predicate to the incoming edge's `condition` if this step was meant to be conditional. (#4414)",rule:Fg})}for(let n of t){if(n.type!==`decision`)continue;let t=typeof n.id==`string`?n.id:``;if(!t)continue;let a=i.get(t)??[];if(a.length===0)continue;let o=n.config??{},s=new Set((Array.isArray(o.conditions)?o.conditions:[]).map(e=>typeof e?.label==`string`?e.label.trim().toLowerCase():``).filter(Boolean)),c=new Set(a.map(a_).filter(Boolean)),l=[...s].filter(e=>!c.has(e));l.length>0&&r.push({where:`${e} \xB7 decision '${t}'`,message:`declares branch label(s) ${l.map(e=>`'${e}'`).join(`, `)} that no out-edge carries \u2014 out-edge labels are [${[...c].map(e=>`'${e}'`).join(`, `)||`none`}]. Traversal cannot honour a label nothing claims, so it falls back to considering EVERY out-edge and the branch the decision computed is ignored.`,hint:"Make an out-edge's `label` match the declared branch exactly, or drop `config.conditions` and branch on the edges instead (`condition` per branch + `isDefault: true` on the fallback) — one mechanism per decision, never both. (#4414)",rule:jg,severity:`error`});let u=a.filter(e=>e.condition||e.isDefault===!0),d=Array.isArray(o.conditions)&&o.conditions.length>0;if(u.length===0){d||r.push({where:`${e} \xB7 decision '${t}'`,message:`gates on NOTHING \u2014 none of its out-edge(s) (${a.map(e=>`'${String(e.target)}'`).join(`, `)}) carries a \`condition\` or \`isDefault\`, and the decision declares no \`config.conditions[]\`. With no branch to select, EVERY out-edge is traversed on EVERY pass, in parallel \u2014 the node is typed \`decision\` but routes exactly as a non-decision step would, so the gateway is decoration.`,hint:"Declare the branching one way and one way only: a `condition` per branch plus `isDefault: true` on the fallback, or `config.conditions[]` whose `label` matches an out-edge's. If the unconditional fan-out is what you meant, drop `type: 'decision'` and use the node it already behaves as.",rule:Mg});continue}let f=a.filter(e=>!e.condition&&e.isDefault!==!0&&!s.has(a_(e)));f.length>0&&r.push({where:`${e} \xB7 decision '${t}'`,message:`has guarded out-edge(s) alongside unconditional one(s) (${f.map(e=>`'${String(e.target)}'`).join(`, `)}) \u2014 an unconditional out-edge is traversed on EVERY pass, in parallel with whichever guarded branch matched, so the decision does not actually exclude it. A \`label\` alone does not select a path unless the decision declares a matching \`conditions[].label\`.`,hint:"Mark the fallback `isDefault: true` so it is taken only when no sibling condition matched (BPMN default flow), or give it its own `condition`. (#4414)",rule:Mg})}}function c_(e){return e==null?!0:typeof e!=`object`||Array.isArray(e)?!1:we(e)===`true`}function l_(e){return e==null?"no `filter` key":Object.keys(e).length===0?"an EMPTY `filter`":`a \`filter\` that REDUCES TO TRUE (\`${u_(e)}\`)`}function u_(e){try{let t=JSON.stringify(e);return typeof t==`string`?t.length>80?`${t.slice(0,77)}...`:t:typeof e}catch{return typeof e}}function d_(e,t,n){for(let r of t){let t=typeof r.type==`string`?r.type:``,i=Kg.get(t);if(!i)continue;let a=r.config??{};if(a.multi!==!0||!c_(a.filter))continue;let o=typeof a.objectName==`string`&&a.objectName?a.objectName:`(unnamed object)`,s=l_(a.filter);n.push({where:`${e} \xB7 node '${String(r.id)}' (${t})`,message:`declares \`multi: true\` with ${s} \u2014 this is a WHOLE-OBJECT write, by declaration: every row of '${o}' is ${i.verb} on every run. The executor forwards the filter as \`where\` (an absent key becomes \`{}\`) plus the bulk intent, ${i.dispatchNote}, and it lands on \`${i.engineCall}\` bounded by nothing \u2014 a filter that reduces to TRUE constrains no row. Nothing refuses it at run time, so the only feedback is the step's \`acted\` row count \u2014 reported AFTER the rows are gone.`,hint:`Write the constraint you mean into \`filter\` (e.g. \`{ status: 'closed' }\` \u2014 see examples/app-showcase \`showcase_inquiry_purge\`, bulk intent bounded by a predicate). If emptying '${o}' really is the intent, keep it: this is a warning, not a gate, and the run-time path stays open. Distinct from the #3810 erased-condition guard, which REFUSES this node at run time when a condition you WROTE interpolated to nothing \u2014 that guard is keyed on "a written condition is gone" and deliberately not on "the filter is empty", which is the fact this rule judges at authoring time. (#5482, #5393)`,rule:Ig})}}function f_(e,t,n,r){let i=t.filter(e=>e.type===He);if(i.length===0)return;let a=new Set(t.map(e=>typeof e.id==`string`?e.id:``).filter(Boolean)),o=new Map(t.filter(e=>typeof e.id==`string`).map(e=>[e.id,typeof e.type==`string`?e.type:``])),s=new Map;for(let e of n){let t=typeof e.source==`string`?e.source:``;t&&(s.has(t)||s.set(t,[]),s.get(t).push(e))}for(let t of i){let i=typeof t.id==`string`?t.id:``;if(!i)continue;let c=n.filter(e=>e.source===i&&a_(e)===`revise`).map(e=>typeof e.target==`string`?e.target:``).filter(e=>e&&a.has(e));if(c.length===0)continue;let l=`${e} \xB7 approval '${i}'`;for(let e of c){let t=o.get(e)??``;t!==`approval_revise`&&r.push({where:l,severity:`error`,message:`has a 'revise' out-edge into node '${e}' of type '${t||`(untyped)`}' \u2014 the revise window must be an '${ot}' node. Send-back parks the run there while the record is unlocked, and only the approvals service may continue it (submitter-only, audited, and refusing a colliding pending request); \`sendBack\` refuses any other target, so this flow's revise branch cannot run.`,hint:`Set node '${e}' to \`type: '${ot}'\` (drop any \`waitEventConfig\` \u2014 the window is ended by POST /api/v1/approvals/requests/:id/resubmit, not by a signal). ADR-0044 D3 originally said 'wait' here; its 2026-07-28 amendment reversed that, because a 'wait' is resumable by anyone with the run id (#3823, #3801).`,rule:Og})}(t.config??{}).maxRevisions===0&&r.push({where:l,message:"declares a 'revise' out-edge but `maxRevisions: 0` disables send-back — every revise auto-rejects, so the revise branch never runs.",hint:"Set `maxRevisions` >= 1 to allow N send-backs before auto-reject, or drop the 'revise' edge if send-back isn't intended (ADR-0044).",rule:Dg});let u=new Set(c),d=[...c],f=[];for(;d.length;){let e=d.shift();for(let t of s.get(e)??[]){t.target===i&&f.push(t);let e=typeof t.target==`string`?t.target:``;e&&a.has(e)&&!u.has(e)&&(u.add(e),d.push(e))}}f.length===0?r.push({where:l,message:`has a 'revise' out-edge but no path loops back to it — the submitter reworks the record with nowhere to resubmit, so the revise branch dead-ends. (registerFlow accepts this — it's a valid DAG.)`,hint:`Close the loop: the 'revise' edge should reach an '${ot}' node whose resubmit edge returns to '${i}' marked \`type: 'back'\` (ADR-0044). See examples/app-showcase showcase_budget_approval.`,rule:Tg}):f.some(e=>e.type===`back`)||r.push({where:l,message:"has a 'revise' loop that returns to it, but the closing edge isn't declared `type: 'back'` — registerFlow rejects this as an un-declared cycle.",hint:`Mark the resubmit edge (whose target is '${i}') \`type: 'back'\` so cycle validation skips it while it still traverses at runtime; \`maxRevisions\` guards the loop (ADR-0044).`,rule:Eg})}}var p_="`catch: { nodes: [ { id: 'handled', type: 'assignment', label: 'Handled' } ] }` — one bare `assignment` node with no `config` is the shortest handler that works; `edges` and `errorVariable` may both be omitted",m_="A `catch` region cannot be empty: its `nodes` is `.min(1)`, so `catch: {}` and `catch: { nodes: [] }` are both refused by the parse.";function h_(e){if(!e||typeof e!=`object`||Array.isArray(e))return;let t=e.nodes;return Array.isArray(t)?t:void 0}function g_(e,t,n){for(let r of t){if(r.type!==Ug)continue;let t=h_((r.config??{}).body);if(!t)continue;let i=typeof r.id==`string`&&r.id?r.id:`(unnamed loop)`,a=(t,r,o)=>{if(!(o>yi))for(let s of t){if(!s||typeof s!=`object`)continue;let t=typeof s.type==`string`?s.type:``;if(t===Hg||t===Ug)continue;let c=typeof s.id==`string`&&s.id?s.id:`(unnamed node)`;if(Vg.has(t)){n.push({where:`${e} \xB7 ${r} \xB7 node '${c}' (${t})`,message:`runs inside loop '${i}' with no \`try_catch\` between them \u2014 a '${t}' node can return \`success: false\` or throw, and the loop body's failure propagates straight out of the container (\`loop-node.ts\` iterates with a bare \`await\` and has no \`try\`/\`catch\` at all). The first failing item therefore ends the whole run: every later item is never processed, and the work already done is not even reported (measured on the real engine \u2014 a 5-item sweep failing at item 3 touched 3 items and reported \`acted: 0\`).`,hint:`Contain the failure per iteration: put a \`try_catch\` INSIDE the body and move this node into its \`try\` region \u2014 \`loop { body: { nodes: [ { type: 'try_catch', config: { try, catch } } ] } }\`. ${m_} The minimal handler is ${p_}. Measured: with it, all 5 items are processed and the run completes. If this loop is MEANT to stop at the first failure, that is a legitimate reading and this stays a warning. See content/docs/automation/flows.mdx \xA7"Per-iteration containment".`,rule:Lg});continue}let l=vi.get(t);if(!l)continue;let u=s.config??{};for(let e of l){let n=u[e];if(Array.isArray(n)){n.forEach((e,n)=>{let i=h_(e);i&&a(i,`${r} \u2192 ${t} '${c}' branch ${n}`,o+1)});continue}let i=h_(n);i&&a(i,`${r} \u2192 ${t} '${c}' ${e}`,o+1)}}};a(t,`loop '${i}' body`,0)}}function __(e,t,n){for(let r of t){if(r.type!==Hg)continue;let t=r.config??{};if(t.catch!==void 0)continue;let i=typeof r.id==`string`&&r.id?r.id:`(unnamed node)`,a=t.retry!==void 0;n.push({where:`${e} \xB7 node '${i}' (${Hg})`,message:"declares no `catch` region, so it contains NOTHING — when the `try` region fails the container fails with it and the failure propagates exactly as if the nodes had never been wrapped (measured: the no-`catch` run and the unwrapped control produce identical output)."+(a?" Its `retry` policy re-runs the `try` region first, which delays that outcome rather than changing it.":``)+" Inside a `loop` body this is the silent one: the author has recognised the hazard, wrapped the node, and still loses every item after the first failure.",hint:`Add the handler: ${p_}. ${m_} If failing loudly really is the intent, a \`try_catch\` with only \`try\` (and optionally \`retry\`) is a legitimate retry-then-fail shape \u2014 this is a warning, not a gate. See content/docs/automation/flows.mdx \xA7"Per-iteration containment".`,rule:Rg})}}function v_(e){let t=[];for(let n of w(e.flows)){let e=typeof n.name==`string`?n.name:`(unnamed flow)`,r=w(n.nodes),i=Array.isArray(n.edges)?n.edges:[],a=r.find(e=>e.type===`start`)?.config??{};if((typeof a.triggerType==`string`?a.triggerType:``).startsWith(`record-`)){let n=gg(a.condition).trim();n&&yg.test(n)&&t.push({where:`flow '${e}' \xB7 start condition`,message:`record-change trigger uses a date-EQUALITY time condition (\`${n}\`) \u2014 it only fires if the record happens to be written on that exact day, so unattended "N days before" rules never run.`,hint:"Use a SCHEDULE trigger (daily cron) + a range query instead — e.g. a scheduled flow whose get_record filters `end_date` BETWEEN {TODAY()} and {TODAY()+N}. (#1874)",rule:bg})}let o=typeof n.runAs==`string`?n.runAs:`user`,s=Xg(n,a);if(s&&o!==`system`){let n=Gg(r,i);if(n){let r=n.scope?`, in ${n.scope},`:``;t.push({where:`flow '${e}' \xB7 runAs`,message:`${s}-triggered flow runs under ${Wg}, but a ${s} run has no trigger user \u2014 so its data node '${n.node.id}' (${n.node.type})${r} has no identity to scope to and will be REFUSED at run time.`,hint:`Declare \`runAs:'system'\` to make the elevation explicit and intended (the run reads/writes every record). A ${s} flow cannot scope to a user \u2014 there is none. (ADR-0049, ADR-0073 D5, #1888, #3760)`,rule:kg,severity:`error`})}}for(let n of me({nodes:r,edges:i})){let r=n.scope?`flow '${e}' \xB7 ${n.scope}`:`flow '${e}'`,i=w(n.nodes),a=n.edges;for(let e of i){let n=`${r} \xB7 node '${e.id}' (${e.type})`,i=e.config??{};i.filter&&e_(i.filter,`${n} filter`,t);for(let e of Object.keys(i))Zg.has(e)&&t.push({where:n,message:`node config has \`${e}\` \u2014 the automation engine has no aggregate node, so \`${e}\` is silently ignored and this node computes nothing at runtime.`,hint:"Aggregation belongs in the data layer: use `Field.summary` for a cross-object rollup (sum/count of children), or `Field.formula` for a per-record computed value. (#1870)",rule:Sg});let a=[];i_(Ci(e.config,Si(e.type)),void 0,a);for(let e of a)t_.test(e)&&t.push({where:n,message:`double-brace interpolation \`${e.trim().slice(0,80)}\` \u2014 flow node values use SINGLE braces.`,hint:"Use `{var}` (e.g. `{record.title}`). Double-brace `{{ }}` is the formula/template-field dialect, not flow node values. (#1315)",rule:Cg}),n_.test(e)&&t.push({where:n,message:`\`${e.trim().slice(0,80)}\` looks like a reference written as a literal \u2014 a bare \`$ref.field\` is NOT interpolated.`,hint:"Wrap it and bind a variable: `{source.id}` (or `{$User.Id}` for the current user). (#1315)",rule:wg})}f_(r,i,a,t),o_(r,i,a,t),s_(r,i,a,t),d_(r,i,t),g_(r,i,t),__(r,i,t)}}return t}var y_=`liveness-dead-property`,b_=`liveness-experimental-property`,x_=`liveness-planned-property`,S_=`liveness-live-elsewhere-property`;function C_(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function w_(){try{let e=(0,C.createRequire)(import.meta.url).resolve(`@objectstack/spec/package.json`),t=(0,C.join)((0,C.dirname)(e),`liveness`);return(0,C.existsSync)(t)?t:null}catch{return null}}function T_(e,t){let n=new Map,r=(0,C.join)(e,`${t}.json`);if(!(0,C.existsSync)(r))return n;let i;try{i=JSON.parse((0,C.readFileSync)(r,`utf8`))}catch{return n}let a=i.props||{};for(let[e,t]of Object.entries(a)){if(t?.children)for(let[r,i]of Object.entries(t.children))E_(i)&&n.set(`${e}.${r}`,i);E_(t)&&n.set(e,t)}return n}function E_(e){return e?e.authorWarn===!0||e.status===`experimental`:!1}function D_(e){return e==null?!1:typeof e!=`boolean`||e===!0}function O_(e){if(e.status===`experimental`)return{kind:`is experimental — declared but NOT enforced at runtime`,rule:b_,defaultHint:`It is declared in the spec as an experimental guarantee — not yet enforced at runtime.`};if(e.status===`planned`)return{kind:`is planned — declared, and a consumer is being built against it (not read YET)`,rule:x_,defaultHint:`Keep it — a consumer is being built against this property; it has no runtime effect yet.`};if(e.status===`dead`)return{kind:`has no runtime effect (liveness: dead)`,rule:y_,defaultHint:`Remove it — it is declared in the spec but not consumed at runtime.`};if(e.status===`live-elsewhere`)return{kind:`is enforced in a sibling repo, not here (liveness: live-elsewhere)`,rule:S_,defaultHint:"Keep it — nothing reads it when the stack loads here, but a sibling repo enforces it (for `manifest.runtime`, the cloud marketplace publish gate); see the ledger row's evidence for the enforcer."};throw Error(`lintLivenessProperties: ledger entry has unrecognised status ${JSON.stringify(e.status)} \u2014 describe() only knows 'experimental' | 'planned' | 'dead' | 'live-elsewhere'. This is a shipped-ledger integrity bug, not an authoring error: either the ledger JSON has a typo, or a new status was added to the vocabulary without teaching describe() in lint-liveness-properties.ts about it (#11384).`)}function k_(e){let t=w_();return t?new Set(T_(t,e).keys()):new Set}function A_(e,t,n,r,i){for(let[a,o]of r){let r=a.includes(`.`)?j_(t,a):[t[a]];for(let t of r instanceof Array?r:[r]){if(!D_(t))continue;let{kind:r,rule:s,defaultHint:c}=O_(o),l=o.authorHint??o.note??c;i.push({where:n,message:`sets \`${a}\` but this ${e} property ${r}.`,hint:l,rule:s});break}}}function j_(e,t){let n=[e];for(let e of t.split(`.`)){let t=[];for(let r of n){if(typeof r!=`object`||!r)continue;let n=Array.isArray(r)?void 0:r[e];if(Array.isArray(r))for(let n of r)n&&typeof n==`object`&&t.push(n[e]);else t.push(n)}n=t}return n.flatMap(e=>Array.isArray(e)?e:[e])}var M_=[{type:`flow`,key:`flows`},{type:`action`,key:`actions`},{type:`agent`,key:`agents`},{type:`tool`,key:`tools`},{type:`skill`,key:`skills`},{type:`dataset`,key:`datasets`},{type:`permission`,key:`permissions`},{type:`hook`,key:`hooks`},{type:`page`,key:`pages`},{type:`view`,key:`views`},{type:`webhook`,key:`webhooks`},{type:`datasource`,key:`datasources`},{type:`app`,key:`apps`},{type:`book`,key:`books`},{type:`job`,key:`jobs`},{type:`email_template`,key:`emailTemplates`},{type:`mapping`,key:`mappings`},{type:`dashboard`,key:`dashboards`}];function N_(e){let t=w_();if(!t)return[];let n=[],r=T_(t,`object`),i=T_(t,`field`);for(let t of w(e.objects)){if(!C_(t))continue;let e=typeof t.name==`string`?t.name:`(unnamed object)`;if(r.size>0&&A_(`object`,t,`object '${e}'`,r,n),i.size>0)for(let r of w(t.fields))C_(r)&&A_(`field`,r,`object '${e}' \xB7 field '${typeof r.name==`string`?r.name:`(unnamed field)`}'`,i,n)}let a=T_(t,`translation`);if(a.size>0){let t=w(e.translations);for(let e=0;e<t.length;e++){let r=t[e];if(C_(r))for(let[t,i]of Object.entries(r))C_(i)&&A_(`translation`,i,`translation bundle #${e} \xB7 locale '${t}'`,a,n)}}for(let{type:r,key:i}of M_){let a=T_(t,r);if(a.size!==0)for(let t of w(e[i]))C_(t)&&A_(r,t,`${r} '${typeof t.name==`string`?t.name:typeof t.object==`string`?t.object:`(unnamed ${r})`}'`,a,n)}return n}var P_=`autonumber-references-unknown-field`,F_=`autonumber-references-optional-field`,I_=`autonumber-references-self`,L_=`autonumber-unrecognized-token`;function R_(e){let t=[];for(let n of w(e.objects)){let e=typeof n.name==`string`?n.name:`(unnamed object)`,r=w(n.fields),i=new Map;for(let e of r)typeof e.name==`string`&&i.set(e.name,{required:e.required===!0});for(let n of r){if(n.type!==`autonumber`)continue;let r=typeof n.name==`string`?n.name:`(unnamed field)`,a=typeof n.autonumberFormat==`string`?n.autonumberFormat:typeof n.format==`string`?n.format:``;if(!a)continue;let o=Fe(a),s=lt(o),c=`object '${e}' \xB7 field '${r}' (autonumber "${a}")`;for(let e of o){if(e.kind!==`literal`)continue;let n=e.text.match(/\{[^{}]*\}/g);if(n)for(let e of n){let n=e.slice(1,-1),r=/^0+$/.test(n);t.push({where:c,message:r?`format has a second sequence slot \`${e}\` \u2014 only the first \`{0..0}\` counts; this one renders literally as "${e}".`:`format has an unrecognized token \`${e}\` \u2014 it is not a counter/date/{field} token, so it renders literally as "${e}" in every record number.`,hint:r?"Use a single `{0000}` slot; fold any second number into a literal or a {field} token.":`Date tokens are case-sensitive and exact: {YYYY} {YY} {MM} {DD} {YYYYMMDD} (no spaces/punctuation inside). For a field value use {field_name}.`,rule:L_,severity:`warning`})}}for(let n of s){if(n===r){t.push({where:c,message:`format interpolates \`{${n}}\` \u2014 its own value, which does not exist yet when the number is generated.`,hint:"Reference a DIFFERENT field that is set before create (e.g. `{plan_no}{000}`), or drop the token.",rule:I_,severity:`error`});continue}let a=i.get(n);a?a.required||t.push({where:c,message:`format interpolates \`{${n}}\`, but '${n}' is optional \u2014 any record left blank fails autonumber generation at create time.`,hint:`Mark '${n}' as \`required: true\` so it is always set before the record number is rendered.`,rule:F_,severity:`warning`}):t.push({where:c,message:`format interpolates \`{${n}}\`, but object '${e}' has no field named '${n}' \u2014 generation will always throw.`,hint:`Reference an existing field, or remove the \`{${n}}\` token from the format.`,rule:P_,severity:`error`})}}}return t}var z_=`view-key-collision`,B_=`view-ref-form-target-missing`,V_=`view-ref-form-target-kind`,H_=`view-ref-nav-view-missing`,U_=e=>e.includes("${")||e.includes(`{`);function W_(e,t,n){if(t.has(e))return!0;let r=`${n}.`;return!!(!e.includes(`.`)&&t.has(r+e)||e.startsWith(r)&&t.has(e.slice(r.length)))}var G_=(e,t)=>e.startsWith(`${t}.`)?e.slice(t.length+1):e;function K_(e){return{list:e.list,form:e.form,listViews:e.listViews,formViews:e.formViews}}function q_(e){if(typeof e.name==`string`&&e.name)return e.name;if(typeof e.id==`string`&&e.id)return e.id;if(typeof e.object==`string`&&e.object)return e.object;if(typeof e.list?.data?.object==`string`)return e.list.data.object;if(typeof e.form?.data?.object==`string`)return e.form.data.object}function J_(e){let t=[],n=new Map,r=(e,t)=>{let r=n.get(e);r||n.set(e,r=new Set),r.add(t)},i=new Map,a=new Map,o=(e,t,n)=>{let r=n===`list`?i:a,o=r.get(e);o||r.set(e,o=new Set),o.add(t)},s=e=>{for(let t of[e.object,e.objectName,e.data?.object,e.list?.data?.object])if(typeof t==`string`&&t)return t},c=[];for(let t of w(e.views)){if(t.viewKind){let e=t.viewKind===`form`?`form`:`list`;if(typeof t.name==`string`){r(t.name,e);let n=s(t);n&&o(n,t.name,e)}continue}if(!d(t))continue;let e=q_(t);e&&c.push({object:e,container:t})}for(let t of w(e.objects)){let e=typeof t.name==`string`?t.name:void 0;e&&(t.list||t.form||t.listViews||t.formViews)&&c.push({object:e,container:K_(t)})}for(let{object:e,container:n}of c){let{items:i,collisions:a}=m(e,n);for(let t of i)r(t.name,t.viewKind),o(t.object??e,t.name,t.viewKind);for(let n of a)t.push({where:`object '${e}' \xB7 view key '${n.key}'`,message:`View key collision: the ${n.viewKind} view '${n.requested}' clashes with another view in the same container and was renamed to '${n.renamedTo}'. Anything referencing '${n.requested}' (a form action target, a navigation viewName) resolves to the OTHER view, not this one.`,hint:`Give the ${n.viewKind} view a unique key \u2014 the default list implicitly claims '<object>.default'. Renaming key '${n.key}' fixes both this collision and any reference that targets it.`,rule:z_,severity:`warning`})}let l=new Set,u=(e,r)=>{if(!e||e.type!==`form`)return;let i=e.target;if(typeof i!=`string`||!i||i.includes("${")||!i.includes(`.`))return;let a=typeof e.name==`string`?e.name:`(unnamed)`,o=`${a}\0${i}`;if(l.has(o))return;l.add(o);let s=r?`action '${a}' on object '${r}'`:`action '${a}'`,c=n.get(i);if(!c){t.push({where:s,message:`Form action target '${i}' does not resolve to any view. A type:'form' action must point at an existing form view; at runtime this opens a blank/broken form.`,hint:`Check for a typo, or a form view renamed by a key collision. Expected a form view named '<object>.<formViewKey>'.`,rule:B_,severity:`warning`});return}if(!c.has(`form`)){let e=[...c].join(`/`);t.push({where:s,message:`Form action target '${i}' resolves to a ${e} view, not a form view. Opening a ${e} view through a form action renders an empty form (and a submit can silently no-op) at runtime.`,hint:`Point target at a form view (viewKind 'form'). If the form view was renamed by a key collision, fix the colliding key so '${i}' names the form again.`,rule:V_,severity:`error`})}};for(let t of w(e.objects)){let e=typeof t.name==`string`?t.name:void 0;for(let n of w(t.actions))u(n,e)}for(let t of w(e.actions))u(t);let f=new Set,p=(e,n)=>{let r=typeof e.objectName==`string`?e.objectName:void 0,o=typeof e.viewName==`string`?e.viewName:void 0;if(!r||!o||U_(o)||typeof e.recordId==`string`&&e.recordId||e.requiresObject)return;let s=i.get(r);if(!s||s.size===0||W_(o,s,r))return;let c=typeof e.id==`string`&&e.id||typeof e.label==`string`&&e.label||`(unnamed)`,l=JSON.stringify([n,c,r,o]);if(f.has(l))return;f.add(l);let u=[...s].map(e=>G_(e,r)),d=a.get(r),p=!!d&&W_(o,d,r);t.push({where:`app '${n}' \xB7 nav '${c}'`,message:`Navigation entry opens view '${o}' on object '${r}', which declares no such list view. `+(p?`The name resolves to a FORM view of that object, which the object's view switcher never offers. `:``)+`At runtime the name does not resolve and the entry falls back to the object's default view, keeping its authored label and icon \u2014 so the sidebar still reads correctly while opening the wrong view. List views on '${r}': ${Rt(u)}.`,hint:`Correct the name, declare '${o}' in the object's \`listViews\`, or drop \`viewName\` to open the default view.`+(p?` A form view is reachable from a type:'form' action target, not from navigation.`:``)+T(o,u),rule:H_,severity:`error`})},h=(e,t)=>{if(Array.isArray(e))for(let n of e){if(!n||typeof n!=`object`||Array.isArray(n))continue;let e=n;p(e,t),Array.isArray(e.children)&&h(e.children,t)}};for(let[t,n]of w(e.apps).entries()){let e=typeof n.name==`string`&&n.name?n.name:`#${t}`;h(n.navigation,e);for(let t of w(n.areas))h(t.items,e),h(t.navigation,e)}return t}function Y_(e){return`object "${e?.name}"`}function X_(e,t,n,r){let i=(typeof t?.name==`string`&&t.name.trim()?`'${t.name.trim()}'`:``)||(r.length>0?`[${r.join(`, `)}]`:`#${n}`);return`${Y_(e)} \xB7 index ${i}`}function Z_(e,t){return`${Y_(e)} \xB7 field '${t}'`}var Q_=new Set([`lookup`,`master_detail`]),$_=new Set([`number`,`currency`,`integer`,`decimal`,`percent`,`float`,`double`]),ev=new Set([`select`,`multiselect`,`radio`,`enum`]);function tv(e){return se.has(e)||pt.has(e)}var nv=[`name`,`title`,`subject`,`label`,`full_name`,`display_name`,`code`],rv=/_(line|lines|line_item|line_items|item|items|detail|details|entry|entries)$/,iv=[`comment`,`attachment`,`note`,`log`,`audit`,`activity`,`activities`,`history`,`event`,`reaction`,`like`,`mention`,`notification`,`message`];function av(e){return rv.test(e)}function ov(e){let t=e.toLowerCase();return iv.some(e=>t===e||t.endsWith(`_${e}`)||t.endsWith(`_${e}s`))}function sv(e){return e?Array.isArray(e)?e.filter(e=>e&&e.name!=null).map(e=>({name:String(e.name),def:e})):Object.entries(e).map(([e,t])=>({name:e,def:t})):[]}function cv(e){let t=e?.reference;return typeof t==`string`&&t?t:void 0}var lv=`unique/double-declaration`,uv=`unique/unscoped-declared-index`,dv=`unique/legacy-organization-composite`;function fv(e){let t=e?.tenancy?.tenantField;return typeof t==`string`&&t.trim()?t.trim():`organization_id`}function pv(e){return e===!0||e===`global`||e===`organization`}function mv(e){return e===`global`?`global`:`organization`}function hv(e){return e===`organization`?`organization`:`global`}function gv(e){let t=[];if(!Array.isArray(e)||e.length===0)return t;for(let n=0;n<e.length;n++){let r=e[n];if(!r?.name)continue;let i=Array.isArray(r.indexes)?r.indexes:[];for(let e=0;e<i.length;e++){let a=i[e];if(a?.unique!==!0)continue;let o=Array.isArray(a?.fields)?a.fields.filter(e=>typeof e==`string`):[],s=o.join(`, `),c=typeof a?.name==`string`&&a.name.trim()?` '${a.name.trim()}'`:``;t.push({severity:`warning`,rule:uv,where:X_(r,a,e,o),message:`"${r.name}" declares index${c} [${s}] with bare \`unique: true\` \u2014 a unique index whose scope is unstated (ADR-0120). Today the bare spelling materializes over exactly its \`fields\`, i.e. installation-wide; an author who meant "unique per organization" gets no per-organization constraint and no error. Protocol 18 rejects this spelling (#5082).`,path:`objects[${n}].indexes[${e}]`,fix:"State the scope: `unique: 'global'` (installation-wide — exactly today's behavior) or `unique: 'organization'` (one holder per organization — the driver prepends the NULL-safe organization key part at registration)."})}}return t}function _v(e){let t=[];if(!Array.isArray(e)||e.length===0)return t;for(let n=0;n<e.length;n++){let r=e[n];if(!r?.name)continue;let i=Array.isArray(r.indexes)?r.indexes:[];if(i.length===0)continue;let a=new Map;for(let e of i){if(!pv(e?.unique))continue;let t=Array.isArray(e?.fields)?e.fields.filter(e=>typeof e==`string`):[];t.length===1&&(a.has(t[0])||a.set(t[0],e))}if(a.size!==0)for(let{name:e,def:i}of sv(r.fields)){if(!pv(i?.unique))continue;let o=a.get(e);if(!o)continue;let s=mv(i.unique),c=hv(o.unique),l=typeof o?.name==`string`&&o.name.trim()?` '${o.name.trim()}'`:``,u=`\`unique: ${typeof i.unique==`string`?`'${i.unique}'`:i.unique}\``,d=`\`unique: ${typeof o.unique==`string`?`'${o.unique}'`:o.unique}\``,f,p;if(s===c){let t=s===`global`?`installation-wide`:`per-organization`;f=`"${r.name}.${e}" declares field-level ${u} AND a single-column unique index${l} (${d}) on the same column. Both ask for the same ${t} boundary \u2014 the same unique index declared twice (ADR-0120 D5b). Redundant, not contradictory: drop one so the intent has a single home.`,p=s===`global`?`Keep ONE spelling of installation-wide uniqueness: \`unique: 'global'\` on '${e}', or the declared index \u2014 not both.`:`Keep ONE spelling of per-organization uniqueness: \`unique: 'organization'\` on '${e}' (preferred), or the declared \`'organization'\` index \u2014 not both.`}else{let t=s===`global`?`field-level ${u}`:`declared index${l} (${d})`,n=s===`global`?`declared index${l} (${d})`:`field-level ${u}`;f=`"${r.name}.${e}" declares an installation-wide unique (${t}) AND a per-organization unique (${n}) on the same column \u2014 the two scopes CONTRADICT (ADR-0120 D5b). The installation-wide index is physically stricter and wins; the per-organization constraint can never be tripped, so one of the two intents you wrote is silently dead.`,p=`Pick ONE scope and say it once: for installation-wide uniqueness keep \`unique: 'global'\` and drop the per-organization declaration; for per-organization uniqueness set \`unique: 'organization'\` (field-level on '${e}', or on the declared index) and drop the installation-wide one.`}t.push({severity:`warning`,rule:lv,where:Z_(r,e),message:f,path:`objects[${n}]`,fix:p})}}return t}function vv(e){let t=[];if(!Array.isArray(e)||e.length===0)return t;for(let n=0;n<e.length;n++){let r=e[n];if(!r?.name)continue;let i=fv(r),a=Array.isArray(r.indexes)?r.indexes:[];for(let e=0;e<a.length;e++){let o=a[e];if(!pv(o?.unique)||o.unique===`organization`)continue;let s=Array.isArray(o?.fields)?o.fields.filter(e=>typeof e==`string`):[];if(s.length<2||!s.includes(i))continue;let c=typeof o?.name==`string`&&o.name.trim()?` '${o.name.trim()}'`:``,l=`\`unique: ${typeof o.unique==`string`?`'${o.unique}'`:o.unique}\``,u=s.filter(e=>e!==i);t.push({severity:`warning`,rule:dv,where:X_(r,o,e,s),message:`"${r.name}" declares index${c} [${s.join(`, `)}] with ${l} and lists the organization column '${i}' itself \u2014 the hand-written per-organization composite that predates the scope vocabulary (ADR-0120 S6). It reads as "unique per organization" but materializes as a plain composite, and SQL UNIQUE is NULL-distinct: on every row whose '${i}' is NULL it enforces nothing (#5030) \u2014 which on a single-organization deployment is every row.`,path:`objects[${n}].indexes[${e}]`,fix:`State the scope instead: \`unique: 'organization'\` on this index (keep \`fields\` exactly as they are \u2014 the driver makes the listed '${i}' NULL-safe in place rather than prepending a second organization key part). ${u.length>0?`The constraint then really is "one ${u.join(` + `)} per organization". `:``}Opting in is a physical tightening: it surfaces as a \`recreate_index\` drift op gated by the duplicate pre-flight probe (ADR-0120 D4), so pre-existing duplicate NULL-organization rows block it with a report rather than failing a boot. Leaving it as-is stays valid indefinitely and forces no drift.`})}}return t}function yv(e){let t=[...gv(e),..._v(e),...vv(e)];if(!Array.isArray(e)||e.length===0)return t;let n={};for(let t of e)t?.name&&!(t.name in n)&&(n[t.name]=t);let r={};for(let t of e)if(t?.name)for(let{name:e,def:n}of sv(t.fields)){if(!Q_.has(n?.type))continue;let i=cv(n);i&&(r[i]||(r[i]=[])).push({child:t,fieldName:e,def:n})}for(let i=0;i<e.length;i++){let a=e[i];if(!a?.name)continue;let o=`objects[${i}]`,s=sv(a.fields),c=!!a.nameField||s.some(e=>nv.includes(e.name));s.length>0&&!c&&t.push({severity:`suggestion`,rule:`object/missing-name-field`,message:`Object "${a.name}" has no nameField and no name-like field \u2014 records will display as raw IDs`,path:`${o}.fields`,fix:"Set `nameField: '<field>'` — ADR-0079's canonical primary-title pointer — to a stored text/autonumber field, or to a formula field with `returnType: 'text'` for a composite title. A `titleFormat` template does NOT count: it is retired (ADR-0079) and render-only, so the server can neither return nor query the title it renders."});for(let{name:e,def:r}of s){if(!r||typeof r!=`object`)continue;let i=`${o}.fields.${e}`,s=r.type;if(ev.has(s)&&(Array.isArray(r.options)&&r.options.length>0||r.optionsFrom||r.dataSource||r.reference||t.push({severity:`warning`,rule:`field/select-missing-options`,message:`${s} field "${a.name}.${e}" has no options`,path:`${i}.options`})),s===`summary`){let o=r.summaryOperations,s=o?.function,c=o?.object,l=o?.field;if((s===`min`||s===`max`)&&typeof c==`string`&&c!==``&&typeof l==`string`&&l!==``){let r=n[c],o=(r?sv(r.fields).find(e=>e.name===l):void 0)?.def?.type;typeof o==`string`&&!tv(o)&&t.push({severity:`error`,rule:`rollup/non-numeric-aggregand`,message:`summary field "${a.name}.${e}" rolls up ${s}(${c}.${l}), but "${c}.${l}" is a ${o} field \u2014 ${s} answers with a value of the CHILD field's own type, while a summary field's value contract is a finite number (it is a member of the spec's NUMERIC_VALUE_TYPES class), so the answer does not fit the column the roll-up is stored in`,path:`${i}.summaryOperations.field`,fix:`Aggregate a numeric or boolean child field instead (min/max over those answer with a number), or use function: 'count' \u2014 which reads no value off the field. To carry a ${o} on "${a.name}", declare a ${o} field and maintain it from a flow; a roll-up cannot store one.`})}}if(!Q_.has(s))continue;let c=cv(r);if(!c){t.push({severity:`error`,rule:`relationship/missing-reference`,message:`${s} field "${a.name}.${e}" is missing a reference target`,path:`${i}.reference`});continue}s===`master_detail`&&(r.required!==!0&&t.push({severity:`warning`,rule:`relationship/master-detail-required`,message:`master_detail "${a.name}.${e}" \u2192 ${c} should be required (a detail record cannot exist without its master)`,path:`${i}.required`,fix:`required: true`}),r.deleteBehavior===void 0&&t.push({severity:`suggestion`,rule:`relationship/delete-behavior`,message:`master_detail "${a.name}.${e}" \u2192 ${c} should declare deleteBehavior (cascade/restrict \u2014 set_null is not honored on master_detail; use a lookup field if children must survive the parent)`,path:`${i}.deleteBehavior`,fix:`deleteBehavior: 'cascade'`}),av(a.name)&&r.inlineEdit!==!0&&t.push({severity:`suggestion`,rule:`relationship/line-items-inline-edit`,message:`"${a.name}" looks like line items of ${c}; consider inlineEdit: true on "${e}" so it is entered inline within the ${c} form`,path:`${i}.inlineEdit`,fix:`inlineEdit: true`})),s===`lookup`&&av(a.name)&&t.push({severity:`suggestion`,rule:`relationship/line-item-should-be-master-detail`,message:`"${a.name}" looks like line items of ${c} but uses lookup; master_detail gives ownership + cascade + roll-ups`,path:`${i}.type`,fix:`type: 'master_detail'`}),r.inlineEdit===!0&&ov(a.name)&&t.push({severity:`warning`,rule:`relationship/association-inline-edit`,message:`"${a.name}" is an association (comments/audit/activity), not line items \u2014 inlineEdit clutters the ${c} entry form; surface it as a detail-page related list instead`,path:`${i}.inlineEdit`,fix:`remove inlineEdit (use relatedList on the detail page)`})}let l=r[a.name]||[],u=new Set(s.filter(e=>e.def?.type===`summary`).map(e=>e.def?.summaryOperations?.object||e.def?.reference).filter(Boolean)),d=new Set;for(let{child:e,def:n}of l){if(n?.type!==`master_detail`||!e?.name||d.has(e.name)||u.has(e.name))continue;let r=sv(e.fields).find(e=>$_.has(e.def?.type));r&&(d.add(e.name),t.push({severity:`suggestion`,rule:`rollup/missing-summary`,message:`"${a.name}" owns "${e.name}" (master_detail) with numeric field "${r.name}" but has no roll-up summary; consider a summary field (count/sum) on ${a.name}`,path:`${o}.fields`,fix:`summary field aggregating ${e.name}.${r.name}`}))}}return t}var bv=[`validate`,`build`,`lint`],xv=[`cli`,`runtime-publish`],X=bv,Z=[`cli`],Q=[`cli`,`runtime-publish`],$=`P2 (#4463): reads a stack-wide collection the per-write snapshot does not carry, so running it now would report the rest of the tenant's metadata as missing rather than judging this write.`,Sv=`Not runtime-safe: parses authored source through typescript/sucrase, the two dependencies the kernel boot path must never load (lazy-deps.test.ts). Studio compiles page source on its own path.`,Cv=`Advisory-tier object rule: it cannot refuse a write, and it is held off the runtime door for advisory VOLUME (~8 findings per object write measured on unswept metadata, rendered in Studio since #4717), not refusal risk. Crossing it is a UX decision with its own card (#4716).`,wv=`expression-invalid`,Tv=[{name:`validateStackExpressions`,tier:`gating`,input:`parsed`,commands:X,source:`packages/lint/src/validate-expressions.ts`,surfaces:Q,runtimeTypes:[`flow`],run:e=>vr(e).map(e=>({severity:e.severity??`error`,rule:wv,where:e.where,path:e.where,message:e.message,hint:`source: \`${e.source}\``}))},{name:`validateListViewMode`,tier:`gating`,input:`normalized`,commands:X,source:`packages/lint/src/validate-list-view-mode.ts`,surfaces:Z,surfaceReason:$,run:e=>Xr(e)},{name:`validateFunctionalCompleteness`,tier:`gating`,input:`normalized`,commands:X,source:`packages/lint/src/validate-functional-completeness.ts`,surfaces:Q,runtimeTypes:[`object`],run:e=>ei(e)},{name:`validateManagedApiMethods`,tier:`gating`,input:`normalized`,commands:X,source:`packages/lint/src/validate-managed-api-methods.ts`,surfaces:Q,runtimeTypes:[`object`],run:e=>ii(e)},{name:`validateViewContainers`,tier:`gating`,input:`normalized`,commands:X,source:`packages/lint/src/validate-view-containers.ts`,surfaces:Z,surfaceReason:$,run:e=>no(e)},{name:`validateWidgetBindings`,tier:`gating`,input:`parsed`,commands:X,source:`packages/lint/src/validate-widget-bindings.ts`,surfaces:Q,runtimeTypes:[`dashboard`],run:e=>Tn(e)},{name:`validateDashboardActionRefs`,tier:`gating`,input:`parsed`,commands:X,source:`packages/lint/src/validate-dashboard-action-refs.ts`,surfaces:Z,surfaceReason:$,run:e=>ed(e)},{name:`validateFilterTokens`,tier:`gating`,input:`parsed`,commands:X,source:`packages/lint/src/validate-filter-tokens.ts`,surfaces:Z,surfaceReason:$,run:e=>ad(e)},{name:`validateFlowFilterTokens`,tier:`gating`,input:`parsed`,commands:X,source:`packages/lint/src/validate-flow-filter-tokens.ts`,surfaces:Q,runtimeTypes:[`flow`],run:e=>bd(e)},{name:`validatePresetComparands`,tier:`gating`,input:`parsed`,commands:X,source:`packages/lint/src/validate-preset-comparands.ts`,surfaces:Q,runtimeTypes:[`dashboard`,`view`,`object`,`page`,`flow`],run:e=>Jd(e)},{name:`validateEmptyCombinators`,tier:`gating`,input:`parsed`,commands:X,source:`packages/lint/src/validate-empty-combinators.ts`,surfaces:Q,runtimeTypes:[`flow`],run:e=>cf(e)},{name:`validateReferenceIntegrity`,tier:`gating`,input:`parsed`,commands:X,source:`packages/lint/src/reference-integrity-suite.ts`,surfaces:Q,runtimeTypes:[`flow`,`view`,`object`],run:(e,t)=>hg(e,t)},{name:`validateComponentProps`,tier:`advisory`,input:`normalized`,commands:X,source:`packages/lint/src/validate-component-props.ts`,surfaces:Z,surfaceReason:$,run:e=>Ip(e)},{name:`validateComponentTypes`,tier:`gating`,input:`normalized`,commands:X,source:`packages/lint/src/validate-component-types.ts`,surfaces:Z,surfaceReason:`Gating rule held off the runtime door pending the #4716 crossing discipline: a measured false-refusal budget over stored tenant page rows (the in-repo 0-finding measurement covers authored config-file metadata only). Crossing is its own rollout card.`,run:e=>Bp(e)},{name:`validateResponsiveStyles`,tier:`gating`,input:`parsed`,commands:X,source:`packages/lint/src/validate-responsive-styles.ts`,surfaces:Z,surfaceReason:$,run:e=>yo(e)},{name:`validateJsxPages`,tier:`gating`,input:`parsed`,commands:X,source:`packages/lint/src/validate-jsx-pages.ts`,surfaces:Z,surfaceReason:Sv,run:(e,t)=>xo(e,t.sduiManifest?{manifest:t.sduiManifest}:{})},{name:`validateReactPages`,tier:`gating`,input:`parsed`,commands:X,source:`packages/lint/src/validate-react-pages.ts`,surfaces:Z,surfaceReason:Sv,run:e=>wo(e)},{name:`validatePageSourceStyling`,tier:`advisory`,input:`parsed`,commands:X,source:`packages/lint/src/validate-page-source-styling.ts`,surfaces:Z,surfaceReason:$,run:e=>Us(e)},{name:`validateCapabilityReferences`,tier:`advisory`,input:`parsed`,commands:X,source:`packages/lint/src/validate-capability-references.ts`,surfaces:Z,surfaceReason:`P2 (#4463): the ONE rule the runtime universe makes strictly stronger — the advisory hedge ("another installed package may provide it") is decidable against the live capability registry, so it graduates from advisory to gating there rather than merely being ported. That promotion is a severity change on a published rule id and belongs in its own PR, not riding a wiring change.`,run:e=>ml(e)},{name:`validateFlowTriggerReadiness`,tier:`gating`,input:`normalized`,commands:X,source:`packages/lint/src/validate-flow-trigger-readiness.ts`,surfaces:Q,runtimeTypes:[`flow`],run:e=>hi(e)},{name:`validateApprovalApprovers`,tier:`gating`,input:`parsed`,commands:X,source:`packages/lint/src/validate-approval-approvers.ts`,surfaces:Q,runtimeTypes:[`flow`],run:e=>jl(e)},{name:`validateRecordTitle`,tier:`advisory`,input:`parsed`,commands:X,source:`packages/lint/src/validate-record-title.ts`,surfaces:Z,surfaceReason:Cv,run:e=>Ks(e)},{name:`validateFieldConsumers`,tier:`advisory`,input:`normalized`,commands:X,source:`packages/lint/src/validate-field-consumers.ts`,surfaces:Z,surfaceReason:$,run:e=>dh(e)},{name:`validateSemanticRoles`,tier:`advisory`,input:`parsed`,commands:X,source:`packages/lint/src/validate-semantic-roles.ts`,surfaces:Z,surfaceReason:Cv,run:e=>Qs(e)},{name:`validateFormLayout`,tier:`advisory`,input:`parsed`,commands:X,source:`packages/lint/src/validate-form-layout.ts`,surfaces:Z,surfaceReason:$,run:e=>uc(e)},{name:`validateActionLocations`,tier:`advisory`,input:`parsed`,commands:X,source:`packages/lint/src/validate-action-locations.ts`,surfaces:Z,surfaceReason:$,run:e=>up(e)},{name:`validateSeedReplaySafety`,tier:`advisory`,input:`parsed`,commands:X,source:`packages/lint/src/validate-seed-replay-safety.ts`,surfaces:Z,surfaceReason:$,run:e=>Nl(e)},{name:`validateSeedStateMachine`,tier:`advisory`,input:`parsed`,commands:X,source:`packages/lint/src/validate-seed-state-machine.ts`,surfaces:Z,surfaceReason:$,run:e=>Ll(e)},{name:`validateVisibilityPredicates`,tier:`gating`,input:`normalized`,commands:X,source:`packages/lint/src/validate-visibility-predicates.ts`,surfaces:Q,runtimeTypes:[`view`],run:e=>Hc(e)},{name:`validatePredicatePathRefs`,tier:`gating`,input:`normalized`,commands:X,source:`packages/lint/src/validate-predicate-path-refs.ts`,surfaces:Q,runtimeTypes:[`view`],run:e=>ul(e)},{name:`lintFlowPatterns`,tier:`gating`,input:`parsed`,commands:X,source:`packages/lint/src/lint-flow-patterns.ts`,surfaces:Q,runtimeTypes:[`flow`],run:e=>v_(e).map(e=>({severity:e.severity??`warning`,rule:e.rule,where:e.where,path:e.where,message:e.message,hint:e.hint}))},{name:`lintLivenessProperties`,tier:`advisory`,input:`parsed`,commands:X,source:`packages/lint/src/lint-liveness-properties.ts`,surfaces:Z,surfaceReason:Cv,run:e=>N_(e).map(e=>({severity:`warning`,rule:e.rule,where:e.where,path:e.where,message:e.message,hint:e.hint}))},{name:`lintAutonumberFormats`,tier:`gating`,input:`parsed`,commands:X,source:`packages/lint/src/lint-autonumber-formats.ts`,surfaces:Q,runtimeTypes:[`object`],run:e=>R_(e).map(e=>({severity:e.severity,rule:e.rule,where:e.where,path:e.where,message:e.message,hint:e.hint}))},{name:`lintViewRefs`,tier:`gating`,input:`parsed`,commands:X,source:`packages/lint/src/lint-view-refs.ts`,surfaces:Z,surfaceReason:$,run:e=>J_(e).map(e=>({severity:e.severity,rule:e.rule,where:e.where,path:e.where,message:e.message,hint:e.hint}))},{name:`lintUnscopedDeclaredIndexes`,tier:`advisory`,input:`parsed`,commands:[`validate`,`build`],source:`packages/lint/src/data-model-rules.ts`,surfaces:Z,surfaceReason:Cv,scopeReason:"`os lint` already reports this rule through `lintDataModel`, which calls it directly ahead of R10 in its best-practice sweep — registering it for `lint` as well would report every finding twice. This is coverage recorded, not coverage missing: all three commands report the rule.",run:e=>gv(Array.isArray(e.objects)?e.objects:[]).map(e=>({severity:e.severity===`suggestion`?`info`:e.severity,rule:e.rule,where:e.where,path:e.path,message:e.message,hint:e.fix??``}))},{name:`lintUniqueDeclarations`,tier:`advisory`,input:`parsed`,commands:[`validate`,`build`],source:`packages/lint/src/data-model-rules.ts`,surfaces:Z,surfaceReason:Cv,scopeReason:"`os lint` already reports this rule through `lintDataModel`, which calls it directly as R10 of its best-practice sweep — registering it for `lint` as well would report every finding twice. This is coverage recorded, not coverage missing: all three commands report the rule.",run:e=>_v(Array.isArray(e.objects)?e.objects:[]).map(e=>({severity:e.severity===`suggestion`?`info`:e.severity,rule:e.rule,where:e.where,path:e.path,message:e.message,hint:e.fix??``}))},{name:`lintLegacyOrganizationComposites`,tier:`advisory`,input:`parsed`,commands:[`validate`,`build`],source:`packages/lint/src/data-model-rules.ts`,surfaces:Z,surfaceReason:Cv,scopeReason:"`os lint` already reports this rule through `lintDataModel`, which calls it directly alongside R10/R11 in its best-practice sweep — registering it for `lint` as well would report every finding twice. This is coverage recorded, not coverage missing: all three commands report the rule.",run:e=>vv(Array.isArray(e.objects)?e.objects:[]).map(e=>({severity:e.severity===`suggestion`?`info`:e.severity,rule:e.rule,where:e.where,path:e.path,message:e.message,hint:e.fix??``}))},{name:`validateSecurityPosture`,tier:`gating`,input:`parsed`,commands:X,source:`packages/lint/src/validate-security-posture.ts`,surfaces:Q,runtimeTypes:[`seed`,`permission`,`book`,`object`],run:e=>hu(e)},{name:`validateSecurityRoleWord`,tier:`gating`,input:`parsed`,commands:X,source:`packages/lint/src/validate-security-posture.ts`,surfaces:Z,surfaceReason:`P2 (#4463)/#8310: judges six collections (objects, fields, actions, permission sets, positions, apps — plus books), and the per-write snapshot neither carries nor maps positions/apps. Wiring it for the mapped types alone would enforce one rule id for three of its six collections — the #7220 split (an object named sales_role refused while a position named sales_role walks through). It crosses whole — positions/apps carried, mapped and declared — or stays behind; it stays behind until that wiring exists.`,run:e=>gu(e)},{name:`validateOrgAxisRedLines`,tier:`gating`,input:`parsed`,commands:X,source:`packages/lint/src/validate-org-axis-red-lines.ts`,surfaces:Z,surfaceReason:$,run:e=>Tu(e)},{name:`validateSharingRuleEnforceability`,tier:`gating`,input:`parsed`,commands:X,source:`packages/lint/src/validate-sharing-rule-enforceability.ts`,surfaces:Z,surfaceReason:"P2 (#4463): a sharing rule is not a `flow`, and P1 gates `flow` alone. This entry used to add that the rule reads ONLY `stack.sharingRules[].condition` and needs no other collection, so crossing was a lone `runtimeTypes` edit. #9698 FALSIFIED that: the anchor arm resolves `sharingRules[].object` against `stack.objects` to read the anchor's OWD, so the rule is now cross-collection. `objects` IS carried by the per-write snapshot (`CONTEXT_STACK_KEYS`, #8309), so the remaining gap is unchanged in SHAPE — the gate must accept a `sharing_rule` type and the snapshot must carry `sharingRules`, which it does not — but it is now TWO collections, not one. Crossing with `sharingRules` uncarried would enforce this id for zero of its inputs while the entry claimed the door (#7220). Recorded as pending rather than done, because a rule that has never run at a door should not claim it.",run:e=>Lu(e)},{name:`validateRlsPredicateEnforceability`,tier:`gating`,input:`parsed`,commands:X,source:`packages/lint/src/validate-rls-predicate-enforceability.ts`,surfaces:Z,surfaceReason:"The rule reads `stack.permissions[]`, which the per-write snapshot DOES carry since #8309 — the remaining gap is only the declaration: no `runtimeTypes` names `permission` here, and that flip is a rollout decision on #8310's axis, not a wiring fix. Recorded as pending rather than done, because a rule that has never run at a door should not claim it.",run:e=>Ku(e)},{name:`validateRuleCompilability`,tier:`gating`,input:`parsed`,commands:X,source:`packages/lint/src/validate-rule-compilability.ts`,surfaces:Q,runtimeTypes:[`object`],run:e=>xm(e)},{name:`validateRuleSchemaFormats`,tier:`gating`,input:`parsed`,commands:X,source:`packages/lint/src/validate-rule-schema-formats.ts`,surfaces:Q,runtimeTypes:[`object`],run:e=>Mm(e)}];function Ev(e){return Tv.filter(t=>t.commands.includes(e))}function Dv(e,t){let n=[],r={sduiManifest:t.sduiManifest};for(let i of Ev(e)){let e=i.input===`normalized`?t.normalized:t.parsed??t.normalized;n.push(...i.run(e,r))}return n}function Ov(e){return{errors:e.filter(e=>e.severity===`error`),advisories:e.filter(e=>e.severity!==`error`)}}var kv={flow:`flows`,object:`objects`,view:`views`,action:`actions`,page:`pages`,dashboard:`dashboards`,agent:`agents`,hook:`hooks`,seed:`data`,permission:`permissions`,book:`books`};function Av(e,t){if(!t||typeof t.packageId!=`string`||t.packageId===``)return e;let n=new Set([t.packageId,...t.dependencies]);return e.filter(e=>{if(!e||typeof e!=`object`)return!0;let t=e[jv];return typeof t!=`string`||t===``||t===Mv||n.has(t)?!0:ou(e)})}var jv=`_packageId`,Mv=`sys_metadata`,Nv=Object.keys({objects:!0,permissions:!0,books:!0,datasets:!0,pages:!0});function Pv(e){return Tv.filter(t=>t.surfaces.includes(`runtime-publish`)&&(t.runtimeTypes??[]).includes(e))}function Fv(){let e=new Set;for(let t of Tv)if(t.surfaces.includes(`runtime-publish`))for(let n of t.runtimeTypes??[])e.add(n);return[...e].sort()}function Iv(e){return kv[e]??null}var Lv=e=>`${e.rule}\0${e.where}\0${e.path}\0${e.message}`;function Rv(e){let t=Iv(e.type);if(!t||!e.item||typeof e.item!=`object`)return null;let n=e.item,r=typeof n.name==`string`?n.name:void 0,i={};for(let n of Nv){let a=e.context?.[n]??[],o=n===`objects`?Av(a,e.packageScope):a;i[n]=n===t?o.filter(e=>!r||e?.name!==r):o}return{baseline:i,candidate:{...i,[t]:[...i[t]??[],n]}}}function zv(e,t){let n=new Set(t);return e.filter(e=>n.has(e))}function Bv(e){if(e.length===0)return/(?!)/;let t=e.map(e=>e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)).join(`|`);return RegExp(`^(${t})\\[(\\d+)\\](.*)$`)}var Vv=zv(Nv,new Set(Object.values(kv))),Hv=/^[A-Za-z_][A-Za-z0-9_]*$/,Uv=Bv(Vv);function Wv(e,t){let n=Uv.exec(e);if(!n)return e;let[,r,i,a]=n;if(!Vv.includes(r))return e;let o=t[r]?.[Number(i)],s=o&&typeof o==`object`?o.name:void 0;return typeof s!=`string`||!Hv.test(s)?e:`${r}.${s}${a}`}function Gv(e,t,n){let r=[];for(let i of e)try{r.push(...i.run(t,n))}catch(e){r.push({severity:`warning`,rule:`authoring-rule-threw`,where:i.name,path:i.source,message:`rule ${i.name} threw while judging this write: ${e instanceof Error?e.message:String(e)}`,hint:`This is a bug in the rule, not in the metadata — the write was not blocked by it. Please report it with the body that triggered it.`})}return r}function Kv(e){let t=Pv(e.type),n={errors:[],advisories:[],rulesRun:[]};if(t.length===0)return n;let r=Rv({type:e.type,item:e.item,...e.context===void 0?{}:{context:e.context},...e.packageScope===void 0?{}:{packageScope:e.packageScope}});if(!r)return n;let i={sduiManifest:e.sduiManifest,runtimeWriteType:e.type},a=new Set(Gv(t,r.baseline,i).map(Lv)),o=Gv(t,r.candidate,i).filter(e=>!a.has(Lv(e))).map(e=>{let t=Wv(e.path,r.candidate);return t===e.path?e:{...e,path:t}});return{errors:o.filter(e=>e.severity===`error`),advisories:o.filter(e=>e.severity!==`error`),rulesRun:t.map(e=>e.name)}}var qv=e=>!!e&&typeof e==`object`&&!Array.isArray(e),Jv=e=>qv(e)&&typeof e.dialect==`string`,Yv=l;function Xv(e){return e?e.issues.map(e=>`${e.path.map(String).join(`.`)||`(root)`}: ${e.message}`).join(` | `):`(no issues reported)`}function Zv(e,t,n,r,i,a,o=new Set){if(typeof e==`string`){Jv(t)&&t.source===e&&a.push({page:r,path:n,authored:e,door:i});return}if(typeof e==`object`&&e&&!o.has(e)){o.add(e);try{if(Array.isArray(e)){if(!Array.isArray(t))return;for(let s=0;s<e.length;s++)Zv(e[s],t[s],`${n}[${s}]`,r,i,a,o);return}if(!qv(e)||!qv(t))return;for(let[s,c]of Object.entries(e)){let e=n?`${n}.${s}`:s,l=t[s];if(l===void 0&&typeof c==`string`&&c.length>0){let n=Object.entries(t).find(([,e])=>Jv(e)&&e.source===c);if(n){a.push({page:r,path:e,authored:c,normalizedTo:n[0],door:i});continue}}Zv(c,l,e,r,i,a,o)}}finally{o.delete(e)}}}function Qv(e,t){let r={findings:[],componentParseErrors:[],unmappedTypes:[],unreadableProps:[],componentCount:0};if(!qv(e))return r.pageParseError=`not an object`,r;let i=[],a=n.safeParse(e);a.success?Zv(e,a.data,``,t,`PageSchema`,i):r.pageParseError=Xv(a.error);let o=Ro(e,``);r.componentCount=o.length;for(let{component:e,path:n}of o){let a=n.replace(/^\./,``),o=typeof e.type==`string`?e.type:`(non-string type)`,s=le.safeParse(e);s.success?Zv(e,s.data,a,t,`PageComponentSchema`,i):r.componentParseErrors.push({path:a,type:o,issues:Xv(s.error)});let c=Yv[o];if(!c){r.unmappedTypes.push({path:a,type:o});continue}if(!qv(e.properties))continue;let l=c.safeParse(e.properties);l.success?Zv(e.properties,l.data,`${a}.properties`,t,`ComponentPropsMap`,i):r.unreadableProps.push({path:a,type:o,issues:Xv(l.error)})}let s=new Set;for(let e of i){let t=`${e.page}::${e.path}`;s.has(t)||(s.add(t),r.findings.push(e))}return r.findings.sort((e,t)=>e.path.localeCompare(t.path)),r}function $v(e){return e.map(e=>{let t=e.normalizedTo?` (deprecated key \u2014 parse re-homes it to \`${e.normalizedTo}\`)`:``;return`${e.page} \xB7 ${e.path}${t}
|
|
6
|
-
authored BARE: ${JSON.stringify(e.authored)}
|
|
7
|
-
seen by: ${e.door}
|
|
8
|
-
fix: author the canonical envelope \u2014 P\`\u2026\` (or { dialect: 'cel', source: \u2026 }).
|
|
9
|
-
This page is a raw object literal: nothing parses it, so a bare string
|
|
10
|
-
reaches the wire verbatim and the console routes it to its LEGACY
|
|
11
|
-
evaluator, where a fail-soft predicate stops gating silently.`}).join(`
|
|
12
|
-
|
|
13
|
-
`)}export{Ua as ACTION_API_UPDATE_READONLY_WHEN_FIELD,ka as ACTION_BODY_SOURCE_UNPARSEABLE,Na as ACTION_BODY_WRITE_EXCLUSIONS,Pa as ACTION_BODY_WRITE_PATTERNS,ja as ACTION_BODY_WRITE_PATTERN_IDS,Da as ACTION_BODY_WRITE_UNKNOWN_FIELD,Aa as ACTION_BODY_WRITE_UNPROVISIONED_ANCHOR,np as ACTION_NAME_UNDEFINED,op as ACTION_NO_PLACEMENT,Oa as ACTION_RECORD_WRITE_DISCARDED,Fa as ACTION_RECORD_WRITE_PATTERNS,Ma as ACTION_RECORD_WRITE_PATTERN_IDS,Xh as AGENT_AUTHORING_WITHDRAWN,Lh as AI_SKILL_SURFACE_MISMATCH,Vh as AI_SKILL_TOOL_UNRESOLVED,bl as APPROVAL_APPROVERS_MAY_RESOLVE_EMPTY,wl as APPROVAL_APPROVER_CROSS_ORG_UNSUPPORTED,hl as APPROVAL_APPROVER_NOT_MEMBERSHIP_TIER,gl as APPROVAL_APPROVER_TYPE_DEPRECATED,_l as APPROVAL_APPROVER_TYPE_UNKNOWN,vl as APPROVAL_APPROVER_TYPE_UNSUPPORTED,Cl as APPROVAL_DECISION_OUTPUTS_RESERVED,yl as APPROVAL_ESCALATION_REASSIGN_NO_TARGET,xl as APPROVAL_EXPRESSION_INVALID,Sl as APPROVAL_EXPRESSION_NO_EMPTY_POLICY,bv as AUTHORING_COMMANDS,Tv as AUTHORING_RULES,xv as AUTHORING_SURFACES,L_ as AUTONUMBER_LITERAL_TOKEN,F_ as AUTONUMBER_OPTIONAL_FIELD,I_ as AUTONUMBER_SELF_REFERENCE,P_ as AUTONUMBER_UNKNOWN_FIELD,dl as CAPABILITY_REFERENCE_UNKNOWN,Wp as CHART_AXIS_NOT_SELECTED,Zt as CHART_CONFIG_MISSING,Up as CHART_DATASET_UNKNOWN,$t as CHART_DIMENSIONS_MISSING,Vp as CHART_DIMENSION_UNKNOWN,Xt as CHART_FIELD_UNKNOWN,Qt as CHART_MEASURES_MISSING,Hp as CHART_MEASURE_UNKNOWN,kp as COMPONENT_PROPS_INVALID,Op as COMPONENT_PROPS_UNKNOWN_KEY,Lp as COMPONENT_TYPE_UNKNOWN,Ju as DASHBOARD_ACTION_ROUTE_UNRESOLVED,qu as DASHBOARD_ACTION_TARGET_UNDEFINED,cn as DASHBOARD_FILTER_FIELD_NOT_INCLUDED,on as DASHBOARD_FILTER_FIELD_UNKNOWN,sn as DASHBOARD_FILTER_FIELD_UNPROVISIONED,tm as DATASET_FIELD_NOT_INCLUDED,em as DATASET_FIELD_UNKNOWN,nm as DATASET_FILTER_FIELD_UNKNOWN,$p as DATASET_INCLUDE_UNKNOWN,Qh as DEFAULT_AGENT_LEGACY_ALIAS,Zh as DEFAULT_AGENT_OUTSIDE_ROSTER,wv as EXPRESSION_INVALID,Wm as FIELD_CARRIER_ROOTS,Um as FIELD_CONSUMER_ROOTS,Js as FIELD_GROUP_EMPTY,Ys as FIELD_GROUP_SHADOWED,qs as FIELD_GROUP_UNDECLARED,Bm as FIELD_NO_CONSUMERS,ur as FIELD_RULE_BOUND_ROOTS,Yd as FILTER_EMPTY_COMBINATOR,Xd as FILTER_EMPTY_NODE,xd as FILTER_PRESET_COMPARAND,td as FILTER_TOKEN_UNKNOWN,Tg as FLOW_APPROVAL_REVISE_DEAD_END,Dg as FLOW_APPROVAL_REVISE_DISABLED,Og as FLOW_APPROVAL_REVISE_TARGET_NOT_SERVICE_OWNED,Eg as FLOW_APPROVAL_REVISE_UNMARKED_BACKEDGE,wg as FLOW_BARE_DOLLAR_REF,jg as FLOW_BRANCH_LABEL_UNMATCHED,xg as FLOW_DATE_EQUALITY_FILTER,Mg as FLOW_DECISION_UNCONDITIONAL_BRANCH,Ng as FLOW_DEFAULT_EDGE_WITH_CONDITION,Cg as FLOW_DOUBLE_BRACE_INTERP,oi as FLOW_DRAFT_STATUS_AMBIGUOUS,Ag as FLOW_ERROR_LABEL_NOT_FAULT,gd as FLOW_FILTER_TOKEN_UNKNOWN,Fg as FLOW_INERT_NODE_CONDITION,Lg as FLOW_LOOP_BODY_UNCONTAINED,Pg as FLOW_MULTIPLE_DEFAULT_EDGES,Ig as FLOW_MULTI_WRITE_UNFILTERED,ig as FLOW_NODE_WRITE_UNKNOWN_FIELD,ag as FLOW_NODE_WRITE_UNPROVISIONED_ANCHOR,Sg as FLOW_PHANTOM_AGGREGATION,kg as FLOW_RUNAS_UNSCOPED,fd as FLOW_TEMPLATE_DATE_FUNCTIONS,Oi as FLOW_TEMPLATE_FIELD_UNPROVISIONED,Di as FLOW_TEMPLATE_LOOKUP_TRAVERSAL,Ei as FLOW_TEMPLATE_UNKNOWN_FIELD,pd as FLOW_TEMPLATE_VALUE_FUNCTIONS,bg as FLOW_TIME_RELATIVE_ANTIPATTERN,ci as FLOW_TIME_RELATIVE_DESCRIPTOR_INVALID,li as FLOW_TIME_RELATIVE_DESCRIPTOR_UNROUTABLE,si as FLOW_TRIGGER_UNKNOWN_EVENT,ai as FLOW_TRIGGER_UNKNOWN_OBJECT,ui as FLOW_TRIGGER_UNROUTABLE,Rg as FLOW_TRY_CATCH_WITHOUT_CATCH,Vi as FLOW_UPDATE_READONLY_FIELD,Hi as FLOW_UPDATE_READONLY_WHEN_FIELD,og as FLOW_WRITE_NODE_TYPES,sg as FLOW_WRITE_NODE_TYPES_DEFERRED,ac as FORM_COLSPAN_ABSOLUTE,ic as FORM_FIELD_UNKNOWN,oc as FORM_SECTION_GROUP_UNKNOWN,ga as HOOK_API_UPDATE_READONLY_FIELD,_a as HOOK_API_UPDATE_READONLY_WHEN_FIELD,Qi as HOOK_BODY_SOURCE_UNPARSEABLE,na as HOOK_BODY_WRITE_EXCLUSIONS,ea as HOOK_BODY_WRITE_PATTERNS,ta as HOOK_BODY_WRITE_PATTERN_IDS,Zi as HOOK_BODY_WRITE_UNKNOWN_FIELD,$i as HOOK_BODY_WRITE_UNPROVISIONED_ANCHOR,Vf as LIST_VIEW_FIELD_DOTTED,Bf as LIST_VIEW_FIELD_UNKNOWN,qr as LIST_VIEW_FILTERS_IN_VIEWS_MODE,y_ as LIVENESS_DEAD_PROPERTY,b_ as LIVENESS_EXPERIMENTAL_PROPERTY,S_ as LIVENESS_LIVE_ELSEWHERE_PROPERTY,x_ as LIVENESS_PLANNED_PROPERTY,ti as MANAGED_API_METHOD_UNAFFORDABLE,Dm as MAX_SCHEMA_WALK_DEPTH,nn as MEASURE_AGGREGATE_INCOHERENT,Im as NAV_OBJECT_UNGRANTED,Df as NAV_OBJECT_UNSERVABLE,mf as NAV_TARGET_UNRESOLVED,Fn as NULL_GUARD_HINT,fp as OBJECTUI_DERIVATION_PREDICATES,Zf as OBJECT_FIELD_REF_UNKNOWN,uf as OBJECT_REFERENCE_UNKNOWN,df as OBJECT_REFERENCE_UNREGISTERED_PLATFORM,Dr as OPEN_VOCABULARY_PROBES,vu as ORG_AXIS_CROSS_ORG_BU_GRANT,_u as ORG_AXIS_PERMISSION_INHERITANCE,Wo as PAGE_FIELD_UNKNOWN,Go as PAGE_FIELD_UNPROVISIONED,Ko as PAGE_SECTION_GROUP_UNKNOWN,Vs as PAGE_SOURCE_CLASSNAME,dp as PAGE_VISUALIZATION_WITHOUT_BINDING,xr as PARSE_FAILURE_HINT,Uc as PREDICATE_PATH_UNRESOLVED,Wc as PREDICATE_PATH_UNROOTED,Gc as PREDICATE_RHS_PATH_SHAPED,Or as PRE_SEAL_PHASES,Is as REACT_BLOCK_NEEDS_RECORD_CONTEXT,bs as REACT_CHART_AGGREGATE_INVALID,xs as REACT_CHART_AXIS_UNKNOWN,Ss as REACT_CHART_DRILLDOWN_INVALID,vs as REACT_CHART_FIELD_UNKNOWN,ys as REACT_CHART_FIELD_UNPROVISIONED,hs as REACT_PAGE_SOURCE_UNPARSEABLE,gs as REACT_PROP_DEPRECATED,_s as REACT_PROP_RETIRED,Ga as READONLY_ACTION_WRITE_EXCLUSIONS,Wa as READONLY_ACTION_WRITE_PATTERN_IDS,ya as READONLY_HOOK_WRITE_EXCLUSIONS,va as READONLY_HOOK_WRITE_PATTERN_IDS,mg as REFERENCE_INTEGRITY_RULES,Dt as RELATIONSHIP_FIELD_TYPES,Bu as RLS_PREDICATE_OVER_BUDGET,Ru as RLS_PREDICATE_UNENFORCEABLE,zu as RLS_PREDICATE_UNPARSEABLE,lm as RUNTIME_AJV_OPTIONS,kr as SEAL_MARKERS,To as SEARCHABLE_FIELD_UNKNOWN,Do as SEARCHABLE_FIELD_UNPROVISIONED,Eo as SEARCHABLE_FIELD_UNSEARCHABLE,Hl as SECURITY_ANCHOR_HIGH_PRIVILEGE,Wl as SECURITY_BOOK_AUDIENCE_UNKNOWN_SET,Ql as SECURITY_CBP_AMBIGUOUS_RELATION,Zl as SECURITY_CBP_NO_RELATION,Xl as SECURITY_DELEGATION_MISSING_REASON,Bl as SECURITY_EXTERNAL_WIDER,Jl as SECURITY_FLS_UNKNOWN_FIELD,ql as SECURITY_FLS_UNQUALIFIED_KEY,Yl as SECURITY_GRANT_EXPIRED_AT_AUTHORING,Kl as SECURITY_MASTER_DETAIL_UNGRANTED,zl as SECURITY_OWD_ALIAS,Rl as SECURITY_OWD_UNSET,Gl as SECURITY_PRIVATE_NO_READSCOPE,Ul as SECURITY_ROLE_WORD,Vl as SECURITY_WILDCARD_VAMA,Ml as SEED_INSERT_MODE_DUPLICATES_ON_REPLAY,Pl as SEED_VALUE_OUTSIDE_STATE_MACHINE,Xs as SEMANTIC_ROLE_FIELD_UNKNOWN,Zs as SEMANTIC_ROLE_FIELD_UNPROVISIONED,ku as SHARING_RULE_OBJECT_CONTROLLED_BY_PARENT,Ou as SHARING_RULE_OBJECT_NOT_SHAREABLE,Du as SHARING_RULE_RUNTIME_VARIABLE_CONDITION,Eu as SHARING_RULE_UNLOWERABLE_CONDITION,Mf as SORT_FIELD_UNKNOWN,Pf as SORT_FIELD_UNPROVISIONED,Nf as SORT_FIELD_UNSORTABLE,wr as STARTUP_OPEN_VOCABULARY_VERDICT,Er as STARTUP_SOURCE_UNPARSEABLE,Tr as STARTUP_VERDICT_ASSERTIVE_WORDING,Fr as STARTUP_VERDICT_HINT,io as STYLE_CLASSNAME_TAILWIND,ro as STYLE_NODE_MISSING_ID,ao as STYLE_RESPONSIVE_NO_BASE,oo as STYLE_UNKNOWN_CSS_PROPERTY,so as STYLE_UNKNOWN_TOKEN,tn as TABLE_COUNT_ONLY,Ws as TITLE_FORMAT_RETIRED,Gs as TITLE_UNRESOLVABLE,mh as TRANSLATION_OPTION_KEY_UNKNOWN,Oh as TRANSLATION_SECTION_NAME_MISSING,ph as TRANSLATION_TARGET_UNKNOWN,lv as UNIQUE_DOUBLE_DECLARATION,dv as UNIQUE_LEGACY_ORGANIZATION_COMPOSITE,uv as UNIQUE_UNSCOPED_DECLARED_INDEX,sm as VALIDATION_RULE_REGEX_UNCOMPILABLE,cm as VALIDATION_RULE_SCHEMA_UNCOMPILABLE,Sm as VALIDATION_RULE_SCHEMA_UNKNOWN_FORMAT,Qa as VIEW_CONTAINER_SHAPE,z_ as VIEW_KEY_COLLISION,xf as VIEW_PAGE_UNRESOLVED,V_ as VIEW_REF_FORM_TARGET_KIND,B_ as VIEW_REF_FORM_TARGET_MISSING,H_ as VIEW_REF_NAV_VIEW_MISSING,yc as VISIBILITY_BARE_IDENTIFIER,xc as VISIBILITY_PREDICATE_OVER_BUDGET,bc as VISIBILITY_PREDICATE_SYNTAX,Sc as VISIBILITY_PREDICATE_UNKNOWN_FUNCTION,vc as VISIBILITY_ROOT_MISLAYERED,qt as WIDGET_DATASET_UNKNOWN,Jt as WIDGET_DIMENSION_UNKNOWN,un as WIDGET_FILTER_FIELD_NOT_INCLUDED,ln as WIDGET_FILTER_FIELD_UNKNOWN,rn as WIDGET_LEGACY_ANALYTICS_SHAPE,an as WIDGET_LEGACY_ANALYTICS_UNRENDERABLE,en as WIDGET_MEASURES_MISSING,Yt as WIDGET_MEASURE_UNKNOWN,dn as WIDGET_SORTBY_UNSELECTED,Qv as auditPageExpressionEnvelopes,k_ as authorWarnedProperties,Ev as authoringRulesFor,Nm as buildAccessMatrix,Rv as buildRuntimeWriteSnapshots,Uo as checkSectionGroupRefs,Lf as checkSortDeclaration,hd as classifyFlowTemplateToken,Pt as describeFieldPathVerdict,br as describeParseFailure,Fm as diffAccessMatrix,fa as extractHookBodyWriteSet,da as extractHookBodyWrites,gr as fieldRuleRootIssue,Kr as findStartupRegistryVerdicts,Yn as findUnguardedNullableOperands,Vo as indexObjectFieldGroups,jt as indexObjectGraph,Lo as isSourceAuthoredPage,Ft as isUnjudgeable,Nt as joinablePrefixes,R_ as lintAutonumberFormats,yv as lintDataModel,v_ as lintFlowPatterns,vv as lintLegacyOrganizationComposites,N_ as lintLivenessProperties,_v as lintUniqueDeclarations,gv as lintUnscopedDeclaredIndexes,J_ as lintViewRefs,Rt as listNames,Av as narrowObjectsToPackageClosure,It as nearestName,jm as nearestRegisteredFormat,Zn as nullGuardMessage,$v as renderBareExpressionFindings,Mt as resolveFieldPath,Dv as runAuthoringRules,Kv as runRuntimeAuthoringRules,Pv as runtimeAuthoringRulesFor,Fv as runtimeGatedTypes,Ho as sectionGroupRefs,Ov as splitBySeverity,Iv as stackKeyForType,T as suggestName,Va as validateActionBodyWrites,up as validateActionLocations,ap as validateActionNameRefs,rg as validateAiAgentAuthoring,Bh as validateAiSurfaceAffinity,Yh as validateAiToolReferences,jl as validateApprovalApprovers,ml as validateCapabilityReferences,Qp as validateChartBindings,Ip as validateComponentProps,Bp as validateComponentTypes,ed as validateDashboardActionRefs,om as validateDatasetReferences,cf as validateEmptyCombinators,dh as validateFieldConsumers,ad as validateFilterTokens,bd as validateFlowFilterTokens,dg as validateFlowNodeWrites,Bi as validateFlowTemplatePaths,hi as validateFlowTriggerReadiness,uc as validateFormLayout,ei as validateFunctionalCompleteness,pa as validateHookBodyWrites,xo as validateJsxPages,Xf as validateListViewFieldRefs,Xr as validateListViewMode,ii as validateManagedApiMethods,zm as validateNavAccess,jf as validateNavObjectServability,bf as validateNavTargetRefs,tp as validateObjectFieldRefs,pf as validateObjectReferences,Tu as validateOrgAxisRedLines,ns as validatePageFieldBindings,Us as validatePageSourceStyling,Dp as validatePageVisualizationBindings,ul as validatePredicatePathRefs,Jd as validatePresetComparands,Bs as validateReactPageProps,wo as validateReactPages,Za as validateReadonlyActionWrites,Ji as validateReadonlyFlowWrites,Ea as validateReadonlyHookWrites,Ks as validateRecordTitle,hg as validateReferenceIntegrity,yo as validateResponsiveStyles,Ku as validateRlsPredicateEnforceability,xm as validateRuleCompilability,Mm as validateRuleSchemaFormats,Mo as validateSearchableFields,hu as validateSecurityPosture,gu as validateSecurityRoleWord,Nl as validateSeedReplaySafety,Ll as validateSeedStateMachine,Qs as validateSemanticRoles,Lu as validateSharingRuleEnforceability,Rf as validateSortableFields,vr as validateStackExpressions,Ih as validateTranslatableSections,Th as validateTranslationReferences,no as validateViewContainers,Ef as validateViewPageRefs,Hc as validateVisibilityPredicates,Tn as validateWidgetBindings,Kt as walkFilterFieldKeys,Ro as walkPageComponents};
|