@shapio/cms 0.4.1 → 0.5.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/dist/admin/assets/{AssetTile-CoNClUYS.js → AssetTile-zOf0K0nN.js} +2 -2
- package/dist/admin/assets/{AssetTile-CoNClUYS.js.map → AssetTile-zOf0K0nN.js.map} +1 -1
- package/dist/admin/assets/{AssistError-BoejyShH.js → AssistError-D_vY2CO0.js} +2 -2
- package/dist/admin/assets/{AssistError-BoejyShH.js.map → AssistError-D_vY2CO0.js.map} +1 -1
- package/dist/admin/assets/{BlockMenuItems-B2Jugisa.js → BlockMenuItems-BEnSpClj.js} +2 -2
- package/dist/admin/assets/{BlockMenuItems-B2Jugisa.js.map → BlockMenuItems-BEnSpClj.js.map} +1 -1
- package/dist/admin/assets/{Body-D3GwLGaB.js → Body-B_IVN5wp.js} +2 -2
- package/dist/admin/assets/{Body-D3GwLGaB.js.map → Body-B_IVN5wp.js.map} +1 -1
- package/dist/admin/assets/{Builder-CmT5-8hI.js → Builder-CnEtRudv.js} +2 -2
- package/dist/admin/assets/{Builder-CmT5-8hI.js.map → Builder-CnEtRudv.js.map} +1 -1
- package/dist/admin/assets/{ConfirmDialog-HS8Gc2t3.js → ConfirmDialog-BW-l3Whg.js} +2 -2
- package/dist/admin/assets/{ConfirmDialog-HS8Gc2t3.js.map → ConfirmDialog-BW-l3Whg.js.map} +1 -1
- package/dist/admin/assets/{CopyButton-DS-bAA23.js → CopyButton-CyoUMStc.js} +2 -2
- package/dist/admin/assets/{CopyButton-DS-bAA23.js.map → CopyButton-CyoUMStc.js.map} +1 -1
- package/dist/admin/assets/{CursorPager-C6PyD3wE.js → CursorPager-BW2Dl_hn.js} +2 -2
- package/dist/admin/assets/{CursorPager-C6PyD3wE.js.map → CursorPager-BW2Dl_hn.js.map} +1 -1
- package/dist/admin/assets/{ExternalLink-KdO72pTj.js → ExternalLink-BCI0q9ib.js} +2 -2
- package/dist/admin/assets/{ExternalLink-KdO72pTj.js.map → ExternalLink-BCI0q9ib.js.map} +1 -1
- package/dist/admin/assets/{FocalPoint-C62fRhmM.js → FocalPoint-CxicvlJO.js} +2 -2
- package/dist/admin/assets/{FocalPoint-C62fRhmM.js.map → FocalPoint-CxicvlJO.js.map} +1 -1
- package/dist/admin/assets/{Form-CLEr5Csd.js → Form-DB03drS9.js} +2 -2
- package/dist/admin/assets/{Form-CLEr5Csd.js.map → Form-DB03drS9.js.map} +1 -1
- package/dist/admin/assets/{FormCheckboxGroup-BrXY6qBg.js → FormCheckboxGroup-JP1xzReQ.js} +2 -2
- package/dist/admin/assets/{FormCheckboxGroup-BrXY6qBg.js.map → FormCheckboxGroup-JP1xzReQ.js.map} +1 -1
- package/dist/admin/assets/{FormRadioGroup-BjE1Jhar.js → FormRadioGroup-BvSC8SRm.js} +2 -2
- package/dist/admin/assets/{FormRadioGroup-BjE1Jhar.js.map → FormRadioGroup-BvSC8SRm.js.map} +1 -1
- package/dist/admin/assets/{FormSelectField-g4zrUlhv.js → FormSelectField-BDIVhZh6.js} +2 -2
- package/dist/admin/assets/{FormSelectField-g4zrUlhv.js.map → FormSelectField-BDIVhZh6.js.map} +1 -1
- package/dist/admin/assets/{FormSwitchField-gciThNGV.js → FormSwitchField-OM4F8ln4.js} +2 -2
- package/dist/admin/assets/{FormSwitchField-gciThNGV.js.map → FormSwitchField-OM4F8ln4.js.map} +1 -1
- package/dist/admin/assets/{FormTextareaField-tsS-UXym.js → FormTextareaField-Bw7EkC4H.js} +2 -2
- package/dist/admin/assets/{FormTextareaField-tsS-UXym.js.map → FormTextareaField-Bw7EkC4H.js.map} +1 -1
- package/dist/admin/assets/{HintedLabel-CVe-PIyv.js → HintedLabel-BGidukgy.js} +2 -2
- package/dist/admin/assets/{HintedLabel-CVe-PIyv.js.map → HintedLabel-BGidukgy.js.map} +1 -1
- package/dist/admin/assets/{InfoHint-DtaHU1Cg.js → InfoHint-D3uwei-E.js} +2 -2
- package/dist/admin/assets/{InfoHint-DtaHU1Cg.js.map → InfoHint-D3uwei-E.js.map} +1 -1
- package/dist/admin/assets/{InsertMenuItem-DlzaD9zr.js → InsertMenuItem-DAihGvbw.js} +2 -2
- package/dist/admin/assets/{InsertMenuItem-DlzaD9zr.js.map → InsertMenuItem-DAihGvbw.js.map} +1 -1
- package/dist/admin/assets/{LinkTabs-stM3j4aH.js → LinkTabs-DBXbfzME.js} +2 -2
- package/dist/admin/assets/{LinkTabs-stM3j4aH.js.map → LinkTabs-DBXbfzME.js.map} +1 -1
- package/dist/admin/assets/{Match-ErAxnNAY.js → Match-CgfZTzqs.js} +2 -2
- package/dist/admin/assets/{Match-ErAxnNAY.js.map → Match-CgfZTzqs.js.map} +1 -1
- package/dist/admin/assets/{Panel-ClY9b33D.js → Panel-DDky5_x9.js} +2 -2
- package/dist/admin/assets/{Panel-ClY9b33D.js.map → Panel-DDky5_x9.js.map} +1 -1
- package/dist/admin/assets/{QueryView-C630REML.js → QueryView-C2d392ly.js} +2 -2
- package/dist/admin/assets/{QueryView-C630REML.js.map → QueryView-C2d392ly.js.map} +1 -1
- package/dist/admin/assets/{RadioTile-CD4mel7U.js → RadioTile-CcP78eb_.js} +2 -2
- package/dist/admin/assets/{RadioTile-CD4mel7U.js.map → RadioTile-CcP78eb_.js.map} +1 -1
- package/dist/admin/assets/{RichTextField-CxeVX6C-.js → RichTextField-CeztaFET.js} +2 -2
- package/dist/admin/assets/{RichTextField-CxeVX6C-.js.map → RichTextField-CeztaFET.js.map} +1 -1
- package/dist/admin/assets/{RowTitle-B-7RptyN.js → RowTitle-mkKp4yfl.js} +2 -2
- package/dist/admin/assets/{RowTitle-B-7RptyN.js.map → RowTitle-mkKp4yfl.js.map} +1 -1
- package/dist/admin/assets/{SecretReveal-Dhw_dYxe.js → SecretReveal-mYCzxF96.js} +2 -2
- package/dist/admin/assets/{SecretReveal-Dhw_dYxe.js.map → SecretReveal-mYCzxF96.js.map} +1 -1
- package/dist/admin/assets/{SharedGlyph-97RaO6Bh.js → SharedGlyph-CuDT7OUU.js} +2 -2
- package/dist/admin/assets/{SharedGlyph-97RaO6Bh.js.map → SharedGlyph-CuDT7OUU.js.map} +1 -1
- package/dist/admin/assets/{StepList--0Fiqsq-.js → StepList-BDO0Q3Wc.js} +2 -2
- package/dist/admin/assets/{StepList--0Fiqsq-.js.map → StepList-BDO0Q3Wc.js.map} +1 -1
- package/dist/admin/assets/Structure-CL_0hVci.js +2 -0
- package/dist/admin/assets/{Structure-CoO3iah3.js.map → Structure-CL_0hVci.js.map} +1 -1
- package/dist/admin/assets/{SubNavLink-YjjaDN40.js → SubNavLink-C4eSybWd.js} +2 -2
- package/dist/admin/assets/{SubNavLink-YjjaDN40.js.map → SubNavLink-C4eSybWd.js.map} +1 -1
- package/dist/admin/assets/{SuggestAltButton-Dlyxoypu.js → SuggestAltButton-CxYlhwyd.js} +2 -2
- package/dist/admin/assets/{SuggestAltButton-Dlyxoypu.js.map → SuggestAltButton-CxYlhwyd.js.map} +1 -1
- package/dist/admin/assets/{TextLink-DIqr5zkJ.js → TextLink-DzNaAft6.js} +2 -2
- package/dist/admin/assets/{TextLink-DIqr5zkJ.js.map → TextLink-DzNaAft6.js.map} +1 -1
- package/dist/admin/assets/{Thumbnail-BUYOr4XJ.js → Thumbnail-DSPArZ9h.js} +2 -2
- package/dist/admin/assets/{Thumbnail-BUYOr4XJ.js.map → Thumbnail-DSPArZ9h.js.map} +1 -1
- package/dist/admin/assets/{UnsavedChangesGuard-BfzHgUkF.js → UnsavedChangesGuard-BPOCBD5T.js} +2 -2
- package/dist/admin/assets/{UnsavedChangesGuard-BfzHgUkF.js.map → UnsavedChangesGuard-BPOCBD5T.js.map} +1 -1
- package/dist/admin/assets/{UserAvatar-DNOWhSWS.js → UserAvatar-BHNWHDVb.js} +2 -2
- package/dist/admin/assets/{UserAvatar-DNOWhSWS.js.map → UserAvatar-BHNWHDVb.js.map} +1 -1
- package/dist/admin/assets/{auth-YVfK3SxF.js → auth-BzCgJtgr.js} +2 -2
- package/dist/admin/assets/{auth-YVfK3SxF.js.map → auth-BzCgJtgr.js.map} +1 -1
- package/dist/admin/assets/{badge-lJ4Ih_Zn.js → badge-DBoaS0nQ.js} +2 -2
- package/dist/admin/assets/{badge-lJ4Ih_Zn.js.map → badge-DBoaS0nQ.js.map} +1 -1
- package/dist/admin/assets/{boxes-DRvd25_u.js → boxes-DhN0ctLo.js} +2 -2
- package/dist/admin/assets/{boxes-DRvd25_u.js.map → boxes-DhN0ctLo.js.map} +1 -1
- package/dist/admin/assets/{calendar-clock-VENf4s1R.js → calendar-clock-BEA3tG17.js} +2 -2
- package/dist/admin/assets/{calendar-clock-VENf4s1R.js.map → calendar-clock-BEA3tG17.js.map} +1 -1
- package/dist/admin/assets/{changeSets-JmSyu3tu.js → changeSets-C54Ku-X9.js} +2 -2
- package/dist/admin/assets/{changeSets-JmSyu3tu.js.map → changeSets-C54Ku-X9.js.map} +1 -1
- package/dist/admin/assets/chevron-left-BeJdUVAX.js +2 -0
- package/dist/admin/assets/{chevron-left-D2DnQyeV.js.map → chevron-left-BeJdUVAX.js.map} +1 -1
- package/dist/admin/assets/{circle-check-jmRQz1Jq.js → circle-check-ktACw37r.js} +2 -2
- package/dist/admin/assets/{circle-check-jmRQz1Jq.js.map → circle-check-ktACw37r.js.map} +1 -1
- package/dist/admin/assets/{clock-DrSTMGjp.js → clock-BKNNASKp.js} +2 -2
- package/dist/admin/assets/{clock-DrSTMGjp.js.map → clock-BKNNASKp.js.map} +1 -1
- package/dist/admin/assets/cn-h5ORT3LK.js +2 -0
- package/dist/admin/assets/cn-h5ORT3LK.js.map +1 -0
- package/dist/admin/assets/coerce-DDQ1vGLx.js +2 -0
- package/dist/admin/assets/{coerce-B4MJTGg1.js.map → coerce-DDQ1vGLx.js.map} +1 -1
- package/dist/admin/assets/{constants-ahk0YSYl.js → constants-DH7oqfO_.js} +2 -2
- package/dist/admin/assets/{constants-ahk0YSYl.js.map → constants-DH7oqfO_.js.map} +1 -1
- package/dist/admin/assets/{content-DcvNzKGe.js → content-BptqQO8c.js} +3 -3
- package/dist/admin/assets/{content-DcvNzKGe.js.map → content-BptqQO8c.js.map} +1 -1
- package/dist/admin/assets/{contentCounts-DzIvdeXR.js → contentCounts-BpGlmyeZ.js} +2 -2
- package/dist/admin/assets/{contentCounts-DzIvdeXR.js.map → contentCounts-BpGlmyeZ.js.map} +1 -1
- package/dist/admin/assets/{contentTypes-YAd-AzOF.js → contentTypes-B_mAlIcH.js} +2 -2
- package/dist/admin/assets/{contentTypes-YAd-AzOF.js.map → contentTypes-B_mAlIcH.js.map} +1 -1
- package/dist/admin/assets/{context-4Jl20mYc.js → context-DyyMW7Md.js} +2 -2
- package/dist/admin/assets/{context-4Jl20mYc.js.map → context-DyyMW7Md.js.map} +1 -1
- package/dist/admin/assets/{copy-t6kAFw-O.js → copy-DjzlFY9u.js} +2 -2
- package/dist/admin/assets/{copy-t6kAFw-O.js.map → copy-DjzlFY9u.js.map} +1 -1
- package/dist/admin/assets/{dateTimeLocal-IDUOKulz.js → dateTimeLocal-DFXY779D.js} +2 -2
- package/dist/admin/assets/{dateTimeLocal-IDUOKulz.js.map → dateTimeLocal-DFXY779D.js.map} +1 -1
- package/dist/admin/assets/{develop-DYwiTd6R.js → develop-DJap_z-1.js} +2 -2
- package/dist/admin/assets/{develop-DYwiTd6R.js.map → develop-DJap_z-1.js.map} +1 -1
- package/dist/admin/assets/{dropdown-menu-DiYSm-g3.js → dropdown-menu-DGSMTf23.js} +2 -2
- package/dist/admin/assets/{dropdown-menu-DiYSm-g3.js.map → dropdown-menu-DGSMTf23.js.map} +1 -1
- package/dist/admin/assets/{ellipsis-DEHUaCkn.js → ellipsis-BMP-j3yO.js} +2 -2
- package/dist/admin/assets/{ellipsis-DEHUaCkn.js.map → ellipsis-BMP-j3yO.js.map} +1 -1
- package/dist/admin/assets/{external-link-B8UFREQ_.js → external-link-DzOkt97S.js} +2 -2
- package/dist/admin/assets/{external-link-B8UFREQ_.js.map → external-link-DzOkt97S.js.map} +1 -1
- package/dist/admin/assets/{fileRoute-CVQpW8cj.js → fileRoute-CG0Dufvt.js} +2 -2
- package/dist/admin/assets/{fileRoute-CVQpW8cj.js.map → fileRoute-CG0Dufvt.js.map} +1 -1
- package/dist/admin/assets/{folder-plus-iDg1hhew.js → folder-plus-C-LhI4a2.js} +2 -2
- package/dist/admin/assets/{folder-plus-iDg1hhew.js.map → folder-plus-C-LhI4a2.js.map} +1 -1
- package/dist/admin/assets/{followPlural-BdqfEe48.js → followPlural-D-8kzFOe.js} +2 -2
- package/dist/admin/assets/{followPlural-BdqfEe48.js.map → followPlural-D-8kzFOe.js.map} +1 -1
- package/dist/admin/assets/{globe-TooNSp9V.js → globe-DOoGBy23.js} +2 -2
- package/dist/admin/assets/{globe-TooNSp9V.js.map → globe-DOoGBy23.js.map} +1 -1
- package/dist/admin/assets/{image-CXZXXH58.js → image-D9p_gGE2.js} +2 -2
- package/dist/admin/assets/{image-CXZXXH58.js.map → image-D9p_gGE2.js.map} +1 -1
- package/dist/admin/assets/{image-off-cxva5G-Y.js → image-off-G0M2Nh1I.js} +2 -2
- package/dist/admin/assets/{image-off-cxva5G-Y.js.map → image-off-G0M2Nh1I.js.map} +1 -1
- package/dist/admin/assets/{inbox-B8c9Kj_z.js → inbox-CMzYVMZo.js} +2 -2
- package/dist/admin/assets/{inbox-B8c9Kj_z.js.map → inbox-CMzYVMZo.js.map} +1 -1
- package/dist/admin/assets/{inbox-CnzNfqt9.js → inbox-XaM-nvsM.js} +2 -2
- package/dist/admin/assets/{inbox-CnzNfqt9.js.map → inbox-XaM-nvsM.js.map} +1 -1
- package/dist/admin/assets/{index-D9KL7arJ.js → index-DHmfMpqz.js} +4 -4
- package/dist/admin/assets/{index-D9KL7arJ.js.map → index-DHmfMpqz.js.map} +1 -1
- package/dist/admin/assets/{key-round-CFJ61iCd.js → key-round-HBvMrmMo.js} +2 -2
- package/dist/admin/assets/{key-round-CFJ61iCd.js.map → key-round-HBvMrmMo.js.map} +1 -1
- package/dist/admin/assets/{languages-eh7U4anI.js → languages-BOv0jYhe.js} +2 -2
- package/dist/admin/assets/{languages-eh7U4anI.js.map → languages-BOv0jYhe.js.map} +1 -1
- package/dist/admin/assets/{layers-mGfmMsKE.js → layers-CkZyCaeb.js} +2 -2
- package/dist/admin/assets/{layers-mGfmMsKE.js.map → layers-CkZyCaeb.js.map} +1 -1
- package/dist/admin/assets/{link-2-off-DbZzRN_w.js → link-2-off-UUkSmPIL.js} +2 -2
- package/dist/admin/assets/{link-2-off-DbZzRN_w.js.map → link-2-off-UUkSmPIL.js.map} +1 -1
- package/dist/admin/assets/{link-b2pFaN-A.js → link-Bvqcg7db.js} +2 -2
- package/dist/admin/assets/{link-b2pFaN-A.js.map → link-Bvqcg7db.js.map} +1 -1
- package/dist/admin/assets/{locales-oBD0q1pN.js → locales-DbrcdhZi.js} +2 -2
- package/dist/admin/assets/{locales-oBD0q1pN.js.map → locales-DbrcdhZi.js.map} +1 -1
- package/dist/admin/assets/{media-Cs9LCQcz.js → media-CO0HSS3b.js} +2 -2
- package/dist/admin/assets/{media-Cs9LCQcz.js.map → media-CO0HSS3b.js.map} +1 -1
- package/dist/admin/assets/{media-5ks_0Rre.js → media-ugEyLgwN.js} +2 -2
- package/dist/admin/assets/{media-5ks_0Rre.js.map → media-ugEyLgwN.js.map} +1 -1
- package/dist/admin/assets/{network-DS8MW3AZ.js → network-BfDaUb7D.js} +2 -2
- package/dist/admin/assets/{network-DS8MW3AZ.js.map → network-BfDaUb7D.js.map} +1 -1
- package/dist/admin/assets/{pencil-C7eD5mlZ.js → pencil-BLNGNJmL.js} +2 -2
- package/dist/admin/assets/{pencil-C7eD5mlZ.js.map → pencil-BLNGNJmL.js.map} +1 -1
- package/dist/admin/assets/{plus-BDZHQBlU.js → plus-BXMBYPoB.js} +2 -2
- package/dist/admin/assets/{plus-BDZHQBlU.js.map → plus-BXMBYPoB.js.map} +1 -1
- package/dist/admin/assets/{preload-helper-CJNJ4S3k.js → preload-helper-DEbJbZwX.js} +2 -2
- package/dist/admin/assets/{preload-helper-CJNJ4S3k.js.map → preload-helper-DEbJbZwX.js.map} +1 -1
- package/dist/admin/assets/{publishing-C4YQ4XKt.js → publishing-DKrATBaj.js} +2 -2
- package/dist/admin/assets/{publishing-C4YQ4XKt.js.map → publishing-DKrATBaj.js.map} +1 -1
- package/dist/admin/assets/{radio-group-zOsGAYRP.js → radio-group-BIhT_uEK.js} +2 -2
- package/dist/admin/assets/{radio-group-zOsGAYRP.js.map → radio-group-BIhT_uEK.js.map} +1 -1
- package/dist/admin/assets/{rotate-ccw-DCWwb4Ga.js → rotate-ccw-DqbffhiC.js} +2 -2
- package/dist/admin/assets/{rotate-ccw-DCWwb4Ga.js.map → rotate-ccw-DqbffhiC.js.map} +1 -1
- package/dist/admin/assets/{schedules-DXrBSypK.js → schedules-CETl2eLe.js} +2 -2
- package/dist/admin/assets/{schedules-DXrBSypK.js.map → schedules-CETl2eLe.js.map} +1 -1
- package/dist/admin/assets/{schema-B7L9OJrX.js → schema-CWHuez0q.js} +2 -2
- package/dist/admin/assets/{schema-B7L9OJrX.js.map → schema-CWHuez0q.js.map} +1 -1
- package/dist/admin/assets/{scroll-text-BLThe4Ki.js → scroll-text-DlcDEi2k.js} +2 -2
- package/dist/admin/assets/{scroll-text-BLThe4Ki.js.map → scroll-text-DlcDEi2k.js.map} +1 -1
- package/dist/admin/assets/{search-CcJQqtRw.js → search-Dy2dtwyR.js} +2 -2
- package/dist/admin/assets/{search-CcJQqtRw.js.map → search-Dy2dtwyR.js.map} +1 -1
- package/dist/admin/assets/{searchSchemas-BCRZ1jyL.js → searchSchemas-Cz4P1iku.js} +2 -2
- package/dist/admin/assets/{searchSchemas-BCRZ1jyL.js.map → searchSchemas-Cz4P1iku.js.map} +1 -1
- package/dist/admin/assets/{sections-v5Flaor9.js → sections-BfG6DTFr.js} +2 -2
- package/dist/admin/assets/{sections-v5Flaor9.js.map → sections-BfG6DTFr.js.map} +1 -1
- package/dist/admin/assets/{sections-TIN_Nl1b.js → sections-EgXyXN3-.js} +2 -2
- package/dist/admin/assets/{sections-TIN_Nl1b.js.map → sections-EgXyXN3-.js.map} +1 -1
- package/dist/admin/assets/{select-CpHp3YOH.js → select--mePTdz8.js} +2 -2
- package/dist/admin/assets/{select-CpHp3YOH.js.map → select--mePTdz8.js.map} +1 -1
- package/dist/admin/assets/{send-CbP0Rc9_.js → send-DVgq5Iwg.js} +2 -2
- package/dist/admin/assets/{send-CbP0Rc9_.js.map → send-DVgq5Iwg.js.map} +1 -1
- package/dist/admin/assets/{seo-1n9s7YuX.js → seo-Zhb62Ojz.js} +2 -2
- package/dist/admin/assets/{seo-1n9s7YuX.js.map → seo-Zhb62Ojz.js.map} +1 -1
- package/dist/admin/assets/{settings-CuEO5l07.js → settings-Mscp6tN5.js} +2 -2
- package/dist/admin/assets/{settings-CuEO5l07.js.map → settings-Mscp6tN5.js.map} +1 -1
- package/dist/admin/assets/{skeleton-DElTumgk.js → skeleton-DJVukcn6.js} +2 -2
- package/dist/admin/assets/{skeleton-DElTumgk.js.map → skeleton-DJVukcn6.js.map} +1 -1
- package/dist/admin/assets/{snapshots-DkyyrWX3.js → snapshots-BpLhILlt.js} +2 -2
- package/dist/admin/assets/{snapshots-DkyyrWX3.js.map → snapshots-BpLhILlt.js.map} +1 -1
- package/dist/admin/assets/{sparkles-D88gf3vX.js → sparkles-Dd6S_roX.js} +2 -2
- package/dist/admin/assets/{sparkles-D88gf3vX.js.map → sparkles-Dd6S_roX.js.map} +1 -1
- package/dist/admin/assets/{stableId-DlNKh3HM.js → stableId-DFVM13gJ.js} +2 -2
- package/dist/admin/assets/{stableId-DlNKh3HM.js.map → stableId-DFVM13gJ.js.map} +1 -1
- package/dist/admin/assets/{store-jUWyOXDG.js → store-BP-xStwU.js} +2 -2
- package/dist/admin/assets/{store-jUWyOXDG.js.map → store-BP-xStwU.js.map} +1 -1
- package/dist/admin/assets/{switch-CijNGYkG.js → switch-skVypg5O.js} +2 -2
- package/dist/admin/assets/{switch-CijNGYkG.js.map → switch-skVypg5O.js.map} +1 -1
- package/dist/admin/assets/{table-DQ5ILlSh.js → table-BMbbRUK9.js} +2 -2
- package/dist/admin/assets/{table-DQ5ILlSh.js.map → table-BMbbRUK9.js.map} +1 -1
- package/dist/admin/assets/{tabs-CSqGW9Du.js → tabs-C1lgOg1B.js} +3 -3
- package/dist/admin/assets/{tabs-CSqGW9Du.js.map → tabs-C1lgOg1B.js.map} +1 -1
- package/dist/admin/assets/{textarea-FwSvwmyT.js → textarea-CffBBxoQ.js} +2 -2
- package/dist/admin/assets/{textarea-FwSvwmyT.js.map → textarea-CffBBxoQ.js.map} +1 -1
- package/dist/admin/assets/{theme-CHHVK8Ps.js → theme-RHTVnR9j.js} +2 -2
- package/dist/admin/assets/{theme-CHHVK8Ps.js.map → theme-RHTVnR9j.js.map} +1 -1
- package/dist/admin/assets/{titles-CQYc9nDQ.js → titles-DWiPmNvn.js} +2 -2
- package/dist/admin/assets/{titles-CQYc9nDQ.js.map → titles-DWiPmNvn.js.map} +1 -1
- package/dist/admin/assets/{tokens-C-20gLAT.js → tokens-BqyeN1D-.js} +2 -2
- package/dist/admin/assets/{tokens-C-20gLAT.js.map → tokens-BqyeN1D-.js.map} +1 -1
- package/dist/admin/assets/{tooltip-BXqFQv9N.js → tooltip-BfSF6EyR.js} +2 -2
- package/dist/admin/assets/{tooltip-BXqFQv9N.js.map → tooltip-BfSF6EyR.js.map} +1 -1
- package/dist/admin/assets/{undo-2-CLy2zklL.js → undo-2-p4YlNhBp.js} +2 -2
- package/dist/admin/assets/{undo-2-CLy2zklL.js.map → undo-2-p4YlNhBp.js.map} +1 -1
- package/dist/admin/assets/{useAuditLabels-BJF7M5RY.js → useAuditLabels-DV5gcaaG.js} +2 -2
- package/dist/admin/assets/{useAuditLabels-BJF7M5RY.js.map → useAuditLabels-DV5gcaaG.js.map} +1 -1
- package/dist/admin/assets/{useConfirmTarget-BUvlrGSW.js → useConfirmTarget-DCvnxNVg.js} +2 -2
- package/dist/admin/assets/{useConfirmTarget-BUvlrGSW.js.map → useConfirmTarget-DCvnxNVg.js.map} +1 -1
- package/dist/admin/assets/{useContentSchema-Cvtes34f.js → useContentSchema-z6tNif86.js} +2 -2
- package/dist/admin/assets/{useContentSchema-Cvtes34f.js.map → useContentSchema-z6tNif86.js.map} +1 -1
- package/dist/admin/assets/{useCursorPager-CzB6NDOB.js → useCursorPager-CQGX41_L.js} +2 -2
- package/dist/admin/assets/{useCursorPager-CzB6NDOB.js.map → useCursorPager-CQGX41_L.js.map} +1 -1
- package/dist/admin/assets/{useDiscardGuard-BAEGkGK9.js → useDiscardGuard-Dhbif7VL.js} +2 -2
- package/dist/admin/assets/{useDiscardGuard-BAEGkGK9.js.map → useDiscardGuard-Dhbif7VL.js.map} +1 -1
- package/dist/admin/assets/{useMediaPickerDialog-CiN_pias.js → useMediaPickerDialog-D-5uKsMG.js} +2 -2
- package/dist/admin/assets/{useMediaPickerDialog-CiN_pias.js.map → useMediaPickerDialog-D-5uKsMG.js.map} +1 -1
- package/dist/admin/assets/{useMediaUploader-CapEHBIt.js → useMediaUploader-BtLoimmQ.js} +2 -2
- package/dist/admin/assets/{useMediaUploader-CapEHBIt.js.map → useMediaUploader-BtLoimmQ.js.map} +1 -1
- package/dist/admin/assets/{usePaletteItems-wpn3ms6o.js → usePaletteItems-D3PZsW0Q.js} +2 -2
- package/dist/admin/assets/{usePaletteItems-wpn3ms6o.js.map → usePaletteItems-D3PZsW0Q.js.map} +1 -1
- package/dist/admin/assets/{usePlaces-6iTN15Xy.js → usePlaces-Cj5PljTy.js} +2 -2
- package/dist/admin/assets/{usePlaces-6iTN15Xy.js.map → usePlaces-Cj5PljTy.js.map} +1 -1
- package/dist/admin/assets/{useQueries-CYfcxI0Q.js → useQueries-CeDzli4Z.js} +2 -2
- package/dist/admin/assets/{useQueries-CYfcxI0Q.js.map → useQueries-CeDzli4Z.js.map} +1 -1
- package/dist/admin/assets/{useResolvedScheme-i1EwGHuF.js → useResolvedScheme-DHD-zisP.js} +2 -2
- package/dist/admin/assets/{useResolvedScheme-i1EwGHuF.js.map → useResolvedScheme-DHD-zisP.js.map} +1 -1
- package/dist/admin/assets/{useSchemaScopeAccess-WQKmj8_3.js → useSchemaScopeAccess-BNeVslcv.js} +2 -2
- package/dist/admin/assets/{useSchemaScopeAccess-WQKmj8_3.js.map → useSchemaScopeAccess-BNeVslcv.js.map} +1 -1
- package/dist/admin/assets/{users-BgTNDPXx.js → users-BRefbzuS.js} +2 -2
- package/dist/admin/assets/{users-BgTNDPXx.js.map → users-BRefbzuS.js.map} +1 -1
- package/dist/admin/assets/{users-B01EH47o.js → users-CppI8ctO.js} +2 -2
- package/dist/admin/assets/{users-B01EH47o.js.map → users-CppI8ctO.js.map} +1 -1
- package/dist/admin/assets/{zod-79xzBIrW.js → zod-Dcwk-m8X.js} +2 -2
- package/dist/admin/assets/{zod-79xzBIrW.js.map → zod-Dcwk-m8X.js.map} +1 -1
- package/dist/admin/index.html +55 -55
- package/dist/cli.js +110 -18
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/{public-CTK82y3t.d.ts → public-DYR4mtVQ.d.ts} +2 -1
- package/dist/s3Adapter-C8AgFVYw.js +125 -0
- package/dist/s3Adapter-C8AgFVYw.js.map +1 -0
- package/dist/{worker-BDYDbaea.js → worker-jz_0yAmS.js} +388 -358
- package/dist/worker-jz_0yAmS.js.map +1 -0
- package/package.json +8 -5
- package/dist/admin/assets/Structure-CoO3iah3.js +0 -2
- package/dist/admin/assets/chevron-left-D2DnQyeV.js +0 -2
- package/dist/admin/assets/cn-CL1YHRrS.js +0 -2
- package/dist/admin/assets/cn-CL1YHRrS.js.map +0 -1
- package/dist/admin/assets/coerce-B4MJTGg1.js +0 -2
- package/dist/worker-BDYDbaea.js.map +0 -1
|
@@ -7,7 +7,6 @@ import Fastify, { LogController } from "fastify";
|
|
|
7
7
|
import { AliasNode, AndNode, BinaryOperationNode, ColumnNode, ColumnUpdateNode, IdentifierNode, InsertQueryNode, Kysely, ListNode, MysqlAdapter, MysqlIntrospector, MysqlQueryCompiler, OnDuplicateKeyNode, OperationNodeTransformer, OperatorNode, OrNode, OrderByItemNode, ParensNode, PostgresDialect, PrimitiveValueListNode, RawNode, ReferenceNode, SelectAllNode, SelectModifierNode, SelectQueryNode, SelectionNode, SqliteAdapter, SqliteIntrospector, SqliteQueryCompiler, TableNode, UpdateQueryNode, ValueListNode, ValueNode, ValuesNode, WhereNode, sql } from "kysely";
|
|
8
8
|
import pg from "pg";
|
|
9
9
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
10
|
-
import mysql from "mysql2";
|
|
11
10
|
import { EventEmitter } from "node:events";
|
|
12
11
|
import { DatabaseSync } from "node:sqlite";
|
|
13
12
|
import { Type } from "typebox";
|
|
@@ -15,9 +14,6 @@ import { Value } from "typebox/value";
|
|
|
15
14
|
import { isDeepStrictEqual } from "node:util";
|
|
16
15
|
import { createJiti } from "jiti";
|
|
17
16
|
import { pino } from "pino";
|
|
18
|
-
import { DeleteObjectCommand, GetObjectCommand, HeadObjectCommand, PutObjectCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
|
|
19
|
-
import { createPresignedPost } from "@aws-sdk/s3-presigned-post";
|
|
20
|
-
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
|
|
21
17
|
import fp from "fastify-plugin";
|
|
22
18
|
import { hash, verify } from "@node-rs/argon2";
|
|
23
19
|
import cookie from "@fastify/cookie";
|
|
@@ -177,6 +173,20 @@ const sqliteLocationOfUrl = (url) => {
|
|
|
177
173
|
path
|
|
178
174
|
};
|
|
179
175
|
};
|
|
176
|
+
/** `host:port/database` (PostgreSQL, MySQL) or the file path (SQLite) from DATABASE_URL, never the credentials. */
|
|
177
|
+
const describeDatabaseTarget = (connectionString) => {
|
|
178
|
+
if (dialectOfUrl(connectionString) === "sqlite") {
|
|
179
|
+
const location = sqliteLocationOfUrl(connectionString);
|
|
180
|
+
return location.kind === "memory" ? "an in-memory database" : location.path;
|
|
181
|
+
}
|
|
182
|
+
try {
|
|
183
|
+
const url = new URL(connectionString);
|
|
184
|
+
const defaultPort = dialectOfUrl(connectionString) === "mysql" ? "3306" : "5432";
|
|
185
|
+
return `${url.hostname}:${url.port || defaultPort}${url.pathname}`;
|
|
186
|
+
} catch {
|
|
187
|
+
return "the configured database";
|
|
188
|
+
}
|
|
189
|
+
};
|
|
180
190
|
let current;
|
|
181
191
|
/** The dialect queries are built for. PostgreSQL until a database handle says otherwise. */
|
|
182
192
|
const currentDialect = () => current ?? "postgres";
|
|
@@ -1899,9 +1909,10 @@ const MYSQL_TABLES = {
|
|
|
1899
1909
|
"id",
|
|
1900
1910
|
"schema_version",
|
|
1901
1911
|
"permissions_version",
|
|
1902
|
-
"updated_at"
|
|
1912
|
+
"updated_at",
|
|
1913
|
+
"release"
|
|
1903
1914
|
],
|
|
1904
|
-
nullable: [],
|
|
1915
|
+
nullable: ["release"],
|
|
1905
1916
|
timestamps: ["updated_at"],
|
|
1906
1917
|
uniqueKeys: [{
|
|
1907
1918
|
name: "system_versions_pkey",
|
|
@@ -2684,6 +2695,13 @@ const typeCast = (field, next) => {
|
|
|
2684
2695
|
return next();
|
|
2685
2696
|
};
|
|
2686
2697
|
//#endregion
|
|
2698
|
+
//#region src/db/mysql/module.ts
|
|
2699
|
+
/**
|
|
2700
|
+
* mysql2, loaded on first use. A process on PostgreSQL never loads it, and a bundle of the read path (the
|
|
2701
|
+
* in-process delivery runtime) can leave it out as an optional dependency.
|
|
2702
|
+
*/
|
|
2703
|
+
const loadMysql = async () => (await import("mysql2")).default;
|
|
2704
|
+
//#endregion
|
|
2687
2705
|
//#region src/db/mysql/parameters.ts
|
|
2688
2706
|
/**
|
|
2689
2707
|
* Parameters the MySQL connection resolves itself just before a statement runs (ADR 0001, "MySQL").
|
|
@@ -2885,7 +2903,7 @@ var MysqlDriver = class {
|
|
|
2885
2903
|
this.databaseKey = mysqlDatabaseKey(options.url);
|
|
2886
2904
|
}
|
|
2887
2905
|
async init() {
|
|
2888
|
-
const pool =
|
|
2906
|
+
const pool = (await loadMysql()).createPool(mysqlPoolOptions(this.#options.url, this.#options.poolMax, this.#options.applicationName));
|
|
2889
2907
|
pool.on("connection", (connection) => {
|
|
2890
2908
|
connection.query(SESSION_SETUP, (error) => {
|
|
2891
2909
|
if (error) {
|
|
@@ -9435,6 +9453,10 @@ const bumpSchemaVersion = async (trx, now) => {
|
|
|
9435
9453
|
updated_at: now
|
|
9436
9454
|
})).returning("schema_version").executeTakeFirstOrThrow()).schema_version;
|
|
9437
9455
|
};
|
|
9456
|
+
/** Records the Shapio release this database is served by (in-process readers compare their own with it). */
|
|
9457
|
+
const setRelease = async (release, executor = db) => {
|
|
9458
|
+
await executor.updateTable("system_versions").set({ release }).execute();
|
|
9459
|
+
};
|
|
9438
9460
|
//#endregion
|
|
9439
9461
|
//#region src/schema/snapshot.ts
|
|
9440
9462
|
/**
|
|
@@ -12132,13 +12154,20 @@ const groupBindings = (rows) => {
|
|
|
12132
12154
|
return bindings;
|
|
12133
12155
|
};
|
|
12134
12156
|
const KNOWN_ACTIONS = /* @__PURE__ */ new Set([...CONTENT_ACTIONS, ...GLOBAL_ACTIONS]);
|
|
12157
|
+
const KNOWN_CONDITIONS = /* @__PURE__ */ new Set(["ownedByPrincipal"]);
|
|
12158
|
+
/**
|
|
12159
|
+
* A stored grant as this build understands it. Rows written by a newer Shapio may name an action or a row
|
|
12160
|
+
* condition this build does not know; they grant nothing here (fail closed). An unknown condition must never
|
|
12161
|
+
* read as "no condition", which would widen the grant to every row.
|
|
12162
|
+
*/
|
|
12135
12163
|
const toGrant$1 = (row) => {
|
|
12136
12164
|
if (!KNOWN_ACTIONS.has(row.action)) return;
|
|
12165
|
+
if (row.condition !== null && !KNOWN_CONDITIONS.has(row.condition)) return;
|
|
12137
12166
|
return {
|
|
12138
12167
|
roleId: row.role_id,
|
|
12139
12168
|
action: row.action,
|
|
12140
12169
|
modelId: row.model_id,
|
|
12141
|
-
condition: row.condition
|
|
12170
|
+
condition: row.condition,
|
|
12142
12171
|
fieldIds: row.field_ids
|
|
12143
12172
|
};
|
|
12144
12173
|
};
|
|
@@ -13400,6 +13429,20 @@ const SITE_QUERY_PARAMETER = "site";
|
|
|
13400
13429
|
* and the header that selects the site. CDNs that key on the URL only need `?site=` instead of the header.
|
|
13401
13430
|
*/
|
|
13402
13431
|
const DELIVERY_VARY = "Authorization, Cookie, Shapio-Site";
|
|
13432
|
+
//#endregion
|
|
13433
|
+
//#region src/services/contentContext.ts
|
|
13434
|
+
/**
|
|
13435
|
+
* The content service context for one call, the same however the call arrived: the site's view of the pinned
|
|
13436
|
+
* schema (plan site-schema: shared definitions and the site's own), scoped to the site.
|
|
13437
|
+
*/
|
|
13438
|
+
const buildContentContext = ({ network, hooks, media, requestId, ip, ...rest }) => ({
|
|
13439
|
+
...rest,
|
|
13440
|
+
snapshot: network.forSite(rest.site.id),
|
|
13441
|
+
hooks: hooks ?? createContentHooks(),
|
|
13442
|
+
...media ? { media } : {},
|
|
13443
|
+
...requestId !== void 0 ? { requestId } : {},
|
|
13444
|
+
...ip !== void 0 ? { ip } : {}
|
|
13445
|
+
});
|
|
13403
13446
|
const NUMERIC_TYPES = /* @__PURE__ */ new Set([
|
|
13404
13447
|
"number",
|
|
13405
13448
|
"integer",
|
|
@@ -14967,13 +15010,12 @@ const SYSTEM_PRINCIPAL = {
|
|
|
14967
15010
|
kind: "system",
|
|
14968
15011
|
component: EXTENSION_SYSTEM_COMPONENT
|
|
14969
15012
|
};
|
|
14970
|
-
const contentContext = async (environment, site, principal) => ({
|
|
15013
|
+
const contentContext = async (environment, site, principal) => buildContentContext({
|
|
14971
15014
|
db: environment.db,
|
|
14972
|
-
|
|
15015
|
+
network: await environment.registry.getSnapshot(),
|
|
14973
15016
|
permissions: environment.permissions,
|
|
14974
15017
|
actor: principal ?? SYSTEM_PRINCIPAL,
|
|
14975
|
-
site
|
|
14976
|
-
hooks: createContentHooks()
|
|
15018
|
+
site
|
|
14977
15019
|
});
|
|
14978
15020
|
const toReadEntry = (view) => ({
|
|
14979
15021
|
id: view.id,
|
|
@@ -15258,157 +15300,6 @@ const createLoggerOptions = (config) => ({
|
|
|
15258
15300
|
});
|
|
15259
15301
|
const createLogger = (config) => pino(createLoggerOptions(config));
|
|
15260
15302
|
//#endregion
|
|
15261
|
-
//#region src/media/contentDisposition.ts
|
|
15262
|
-
/**
|
|
15263
|
-
* A Content-Disposition value that names the file safely: an ASCII fallback plus the RFC 5987 UTF-8 form,
|
|
15264
|
-
* so quotes, semicolons or line breaks in a filename can never inject header parameters.
|
|
15265
|
-
*/
|
|
15266
|
-
const contentDisposition = (filename, type = "inline") => {
|
|
15267
|
-
return `${type}; filename="${filename.replace(/[^\x20-\x7e]/g, "_").replace(/["\\]/g, "_")}"; filename*=UTF-8''${encodeURIComponent(filename)}`;
|
|
15268
|
-
};
|
|
15269
|
-
/** Types a browser only ever displays passively: opening one directly cannot run script. */
|
|
15270
|
-
const PASSIVE_INLINE_TYPE = /^(image\/(png|jpeg|gif|webp|avif|bmp|tiff|x-icon|vnd\.microsoft\.icon)|video\/.+|audio\/.+)$/;
|
|
15271
|
-
/**
|
|
15272
|
-
* Content-Disposition to store on an object in a bucket. Public objects can be served straight from the
|
|
15273
|
-
* bucket or a CDN, where Shapio's sandboxing headers are absent; anything that could run as a page there
|
|
15274
|
-
* (SVG, HTML, XML, PDF...) is stored as an attachment, so opening it downloads it. `<img>` tags still show
|
|
15275
|
-
* an SVG, since embedding ignores Content-Disposition.
|
|
15276
|
-
*/
|
|
15277
|
-
const bucketContentDisposition = (contentType) => PASSIVE_INLINE_TYPE.test(contentType.toLowerCase()) ? void 0 : "attachment";
|
|
15278
|
-
//#endregion
|
|
15279
|
-
//#region src/media/errors.ts
|
|
15280
|
-
/** Thrown by adapters when a key has no object, so callers can tell "missing" from "storage is down". */
|
|
15281
|
-
var ObjectNotFoundError = class extends Error {
|
|
15282
|
-
constructor(key, options) {
|
|
15283
|
-
super(`No stored object at ${key}`, options);
|
|
15284
|
-
this.name = "ObjectNotFoundError";
|
|
15285
|
-
}
|
|
15286
|
-
};
|
|
15287
|
-
var InvalidStorageKeyError = class extends Error {
|
|
15288
|
-
constructor(key) {
|
|
15289
|
-
super(`Not a valid media storage key: ${JSON.stringify(key)}`);
|
|
15290
|
-
this.name = "InvalidStorageKeyError";
|
|
15291
|
-
}
|
|
15292
|
-
};
|
|
15293
|
-
//#endregion
|
|
15294
|
-
//#region src/media/s3Adapter.ts
|
|
15295
|
-
/** R2 accepts any region name ("auto" by convention); AWS needs the bucket's real region. */
|
|
15296
|
-
const DEFAULT_REGION = "us-east-1";
|
|
15297
|
-
const isNotFound$2 = (error) => error instanceof S3ServiceException && (error.$metadata.httpStatusCode === 404 || error.name === "NotFound" || error.name === "NoSuchKey");
|
|
15298
|
-
const createS3Client = (config) => new S3Client({
|
|
15299
|
-
region: config.region ?? DEFAULT_REGION,
|
|
15300
|
-
...config.endpoint ? { endpoint: config.endpoint } : {},
|
|
15301
|
-
forcePathStyle: config.forcePathStyle,
|
|
15302
|
-
...config.accessKeyId && config.secretAccessKey ? { credentials: {
|
|
15303
|
-
accessKeyId: config.accessKeyId,
|
|
15304
|
-
secretAccessKey: config.secretAccessKey
|
|
15305
|
-
} } : {},
|
|
15306
|
-
requestChecksumCalculation: "WHEN_REQUIRED",
|
|
15307
|
-
responseChecksumValidation: "WHEN_REQUIRED"
|
|
15308
|
-
});
|
|
15309
|
-
/**
|
|
15310
|
-
* Any S3-compatible service (AWS S3, Cloudflare R2, B2, Spaces, Wasabi, versitygw). Private objects are read
|
|
15311
|
-
* through presigned GET URLs; browsers upload straight to the bucket with a presigned POST whose policy
|
|
15312
|
-
* limits size and content type, so Shapio never streams upload bytes.
|
|
15313
|
-
*/
|
|
15314
|
-
const createS3Adapter = ({ config, publicBaseUrl, client }) => {
|
|
15315
|
-
const s3 = client ?? createS3Client(config);
|
|
15316
|
-
const Bucket = config.bucket;
|
|
15317
|
-
const checkKey = (key) => {
|
|
15318
|
-
if (!isValidStorageKey(key)) throw new InvalidStorageKeyError(key);
|
|
15319
|
-
return key;
|
|
15320
|
-
};
|
|
15321
|
-
const head = async (key) => {
|
|
15322
|
-
try {
|
|
15323
|
-
const result = await s3.send(new HeadObjectCommand({
|
|
15324
|
-
Bucket,
|
|
15325
|
-
Key: checkKey(key)
|
|
15326
|
-
}));
|
|
15327
|
-
return {
|
|
15328
|
-
size: result.ContentLength ?? 0,
|
|
15329
|
-
contentType: result.ContentType
|
|
15330
|
-
};
|
|
15331
|
-
} catch (error) {
|
|
15332
|
-
if (isNotFound$2(error)) return;
|
|
15333
|
-
throw error;
|
|
15334
|
-
}
|
|
15335
|
-
};
|
|
15336
|
-
return {
|
|
15337
|
-
driver: "s3",
|
|
15338
|
-
put: async (key, body, { contentType, contentLength }) => {
|
|
15339
|
-
await s3.send(new PutObjectCommand({
|
|
15340
|
-
Bucket,
|
|
15341
|
-
Key: checkKey(key),
|
|
15342
|
-
Body: body,
|
|
15343
|
-
ContentType: contentType,
|
|
15344
|
-
ContentLength: Buffer.isBuffer(body) ? body.length : contentLength,
|
|
15345
|
-
ContentDisposition: bucketContentDisposition(contentType)
|
|
15346
|
-
}));
|
|
15347
|
-
},
|
|
15348
|
-
getStream: async (key, range) => {
|
|
15349
|
-
try {
|
|
15350
|
-
const result = await s3.send(new GetObjectCommand({
|
|
15351
|
-
Bucket,
|
|
15352
|
-
Key: checkKey(key),
|
|
15353
|
-
...range ? { Range: `bytes=${range.start}-${range.end}` } : {}
|
|
15354
|
-
}));
|
|
15355
|
-
if (!result.Body) throw new ObjectNotFoundError(key);
|
|
15356
|
-
return result.Body;
|
|
15357
|
-
} catch (error) {
|
|
15358
|
-
throw isNotFound$2(error) ? new ObjectNotFoundError(key, { cause: error }) : error;
|
|
15359
|
-
}
|
|
15360
|
-
},
|
|
15361
|
-
head,
|
|
15362
|
-
exists: async (key) => await head(key) !== void 0,
|
|
15363
|
-
delete: async (key) => {
|
|
15364
|
-
await s3.send(new DeleteObjectCommand({
|
|
15365
|
-
Bucket,
|
|
15366
|
-
Key: checkKey(key)
|
|
15367
|
-
}));
|
|
15368
|
-
},
|
|
15369
|
-
signedGetUrl: async (key, { expiresInSeconds, filename, contentType }) => getSignedUrl(s3, new GetObjectCommand({
|
|
15370
|
-
Bucket,
|
|
15371
|
-
Key: checkKey(key),
|
|
15372
|
-
ResponseContentType: contentType,
|
|
15373
|
-
ResponseContentDisposition: contentDisposition(filename)
|
|
15374
|
-
}), { expiresIn: expiresInSeconds }),
|
|
15375
|
-
publicUrl: (key) => publicBaseUrl ? `${publicBaseUrl}/${encodeKeyPath(checkKey(key))}` : void 0,
|
|
15376
|
-
presignedUpload: async ({ key, contentType, maxSizeBytes, expiresInSeconds }) => {
|
|
15377
|
-
const disposition = bucketContentDisposition(contentType);
|
|
15378
|
-
const { url, fields } = await createPresignedPost(s3, {
|
|
15379
|
-
Bucket,
|
|
15380
|
-
Key: checkKey(key),
|
|
15381
|
-
Conditions: [
|
|
15382
|
-
[
|
|
15383
|
-
"content-length-range",
|
|
15384
|
-
1,
|
|
15385
|
-
maxSizeBytes
|
|
15386
|
-
],
|
|
15387
|
-
[
|
|
15388
|
-
"eq",
|
|
15389
|
-
"$Content-Type",
|
|
15390
|
-
contentType
|
|
15391
|
-
],
|
|
15392
|
-
...disposition ? [[
|
|
15393
|
-
"eq",
|
|
15394
|
-
"$Content-Disposition",
|
|
15395
|
-
disposition
|
|
15396
|
-
]] : []
|
|
15397
|
-
],
|
|
15398
|
-
Fields: {
|
|
15399
|
-
"Content-Type": contentType,
|
|
15400
|
-
...disposition ? { "Content-Disposition": disposition } : {}
|
|
15401
|
-
},
|
|
15402
|
-
Expires: expiresInSeconds
|
|
15403
|
-
});
|
|
15404
|
-
return {
|
|
15405
|
-
url,
|
|
15406
|
-
fields
|
|
15407
|
-
};
|
|
15408
|
-
}
|
|
15409
|
-
};
|
|
15410
|
-
};
|
|
15411
|
-
//#endregion
|
|
15412
15303
|
//#region src/media/origins.ts
|
|
15413
15304
|
const SAMPLE_KEY = "public/00000000-0000-0000-0000-000000000000/sample/origin-probe";
|
|
15414
15305
|
const originOf = (url) => {
|
|
@@ -15429,6 +15320,7 @@ const resolveMediaOrigins = async (storage) => {
|
|
|
15429
15320
|
const base = originOf(storage.publicBaseUrl);
|
|
15430
15321
|
if (base) origins.add(base);
|
|
15431
15322
|
if (storage.s3) {
|
|
15323
|
+
const { createS3Adapter } = await import("./s3Adapter-C8AgFVYw.js");
|
|
15432
15324
|
const adapter = createS3Adapter({
|
|
15433
15325
|
config: storage.s3,
|
|
15434
15326
|
publicBaseUrl: void 0
|
|
@@ -16086,7 +15978,42 @@ const memoizePermissions = (base, principal) => {
|
|
|
16086
15978
|
};
|
|
16087
15979
|
};
|
|
16088
15980
|
//#endregion
|
|
15981
|
+
//#region src/permissions/scoped.ts
|
|
15982
|
+
const isLazy = (versions) => "read" in versions;
|
|
15983
|
+
/**
|
|
15984
|
+
* The evaluator at the scope's versions. Inside a transaction before a lazy scope read its versions, the
|
|
15985
|
+
* unbound evaluator checks the versions itself through the transaction, so no pooled connection is asked
|
|
15986
|
+
* for while the transaction holds one.
|
|
15987
|
+
*/
|
|
15988
|
+
const boundEvaluator = async (base, versions, executor) => {
|
|
15989
|
+
if (!isLazy(versions)) return base.atVersions?.(versions) ?? base;
|
|
15990
|
+
if (executor && !versions.isRead()) return base;
|
|
15991
|
+
return base.atVersions?.(await versions.read()) ?? base;
|
|
15992
|
+
};
|
|
15993
|
+
/**
|
|
15994
|
+
* One scope's evaluator (an HTTP request, an in-process delivery call): checked against the scope's durable
|
|
15995
|
+
* versions (ADR 0005: a revoke applies from the next scope, not mid-scope) and memoized per (principal, action,
|
|
15996
|
+
* model) for the scope (`memo.ts`).
|
|
15997
|
+
*/
|
|
15998
|
+
const scopePermissions = (base, principal, versions) => memoizePermissions({
|
|
15999
|
+
evaluate: async (caller, policyRequest, executor) => (await boundEvaluator(base, versions, executor)).evaluate(caller, policyRequest, executor),
|
|
16000
|
+
canPerform: async (caller, action, executor) => (await boundEvaluator(base, versions, executor)).canPerform(caller, action, executor),
|
|
16001
|
+
canPerformOnSite: async (caller, action, siteId, executor) => (await boundEvaluator(base, versions, executor)).canPerformOnSite(caller, action, siteId, executor)
|
|
16002
|
+
}, principal);
|
|
16003
|
+
//#endregion
|
|
16004
|
+
//#region src/constants/delivery.ts
|
|
16005
|
+
/** `system_settings` key of the delivery descriptor the server writes at start (services/deliveryDescriptor.ts). */
|
|
16006
|
+
const DELIVERY_DESCRIPTOR_SETTING = "delivery_descriptor";
|
|
16007
|
+
//#endregion
|
|
16089
16008
|
//#region src/repositories/requestState.ts
|
|
16009
|
+
/** The site a lookup names, joined to the one `system_versions` row (at most one row matches). */
|
|
16010
|
+
const siteJoin = (join, lookup) => {
|
|
16011
|
+
switch (lookup.by) {
|
|
16012
|
+
case "id": return join.on("sites.id", "=", lookup.id);
|
|
16013
|
+
case "key": return join.on("sites.key", "=", lookup.key);
|
|
16014
|
+
case "primary": return join.on("sites.is_primary", "=", true);
|
|
16015
|
+
}
|
|
16016
|
+
};
|
|
16090
16017
|
/**
|
|
16091
16018
|
* Everything a request checks before its work, in one statement: the durable schema and permissions versions
|
|
16092
16019
|
* (`system_versions`, one row) and, when asked, the request's site. Read once per request on the pool, before
|
|
@@ -16101,13 +16028,7 @@ const read = async (lookup, trx = db) => {
|
|
|
16101
16028
|
site: void 0
|
|
16102
16029
|
};
|
|
16103
16030
|
}
|
|
16104
|
-
const row = await trx.selectFrom("system_versions").leftJoin("sites", (join) =>
|
|
16105
|
-
switch (lookup.by) {
|
|
16106
|
-
case "id": return join.on("sites.id", "=", lookup.id);
|
|
16107
|
-
case "key": return join.on("sites.key", "=", lookup.key);
|
|
16108
|
-
case "primary": return join.on("sites.is_primary", "=", true);
|
|
16109
|
-
}
|
|
16110
|
-
}).select([
|
|
16031
|
+
const row = await trx.selectFrom("system_versions").leftJoin("sites", (join) => siteJoin(join, lookup)).select([
|
|
16111
16032
|
"system_versions.schema_version",
|
|
16112
16033
|
"system_versions.permissions_version",
|
|
16113
16034
|
"sites.id as site_id",
|
|
@@ -16150,27 +16071,15 @@ const getRequestState = (request, lookup) => {
|
|
|
16150
16071
|
/** Reads the request's site with its state, or on its own when the state was already read without it. */
|
|
16151
16072
|
const readRequestSite = async (request, lookup) => request.requestState ? findSite(lookup) : (await getRequestState(request, lookup)).site;
|
|
16152
16073
|
/**
|
|
16153
|
-
* The server's evaluator at the request's versions. Inside a transaction before the state was read (no route
|
|
16154
|
-
* does that today), the unbound evaluator checks the versions itself through the transaction, so no pooled
|
|
16155
|
-
* connection is asked for while the transaction holds one.
|
|
16156
|
-
*/
|
|
16157
|
-
const boundPermissions = async (request, executor) => {
|
|
16158
|
-
const base = request.server.permissions;
|
|
16159
|
-
if (executor && !request.requestState) return base;
|
|
16160
|
-
const { versions } = await getRequestState(request);
|
|
16161
|
-
return base.atVersions?.(versions) ?? base;
|
|
16162
|
-
};
|
|
16163
|
-
/**
|
|
16164
16074
|
* The request's evaluator: checked against the request's versions, and memoized per (principal, action,
|
|
16165
16075
|
* model) for the request (`permissions/memo.ts`), for REST as for GraphQL. Create it after site resolution,
|
|
16166
16076
|
* which settles the principal.
|
|
16167
16077
|
*/
|
|
16168
16078
|
const getRequestPermissions = (request) => {
|
|
16169
|
-
request.requestPermissions ??=
|
|
16170
|
-
|
|
16171
|
-
|
|
16172
|
-
|
|
16173
|
-
}, request.principal);
|
|
16079
|
+
request.requestPermissions ??= scopePermissions(request.server.permissions, request.principal, {
|
|
16080
|
+
read: async () => (await getRequestState(request)).versions,
|
|
16081
|
+
isRead: () => request.requestState !== null
|
|
16082
|
+
});
|
|
16174
16083
|
return request.requestPermissions;
|
|
16175
16084
|
};
|
|
16176
16085
|
//#endregion
|
|
@@ -16413,12 +16322,14 @@ const revokeApiToken = async (context, permissions, id) => {
|
|
|
16413
16322
|
});
|
|
16414
16323
|
});
|
|
16415
16324
|
};
|
|
16325
|
+
/** Whether a token with this expiry has expired at `now`. */
|
|
16326
|
+
const isTokenExpired = (expiresAt, now) => expiresAt !== null && expiresAt.getTime() <= now.getTime();
|
|
16416
16327
|
/** The principal for a bearer API token, or undefined when unknown, revoked or expired. */
|
|
16417
|
-
const resolveApiToken = async (value, now = /* @__PURE__ */ new Date()) => {
|
|
16418
|
-
const row = await findLiveByHash$1(hashToken(value));
|
|
16419
|
-
if (!row || row.expires_at
|
|
16328
|
+
const resolveApiToken = async (value, now = /* @__PURE__ */ new Date(), { recordUse = true, executor = db } = {}) => {
|
|
16329
|
+
const row = await findLiveByHash$1(hashToken(value), executor);
|
|
16330
|
+
if (!row || isTokenExpired(row.expires_at, now)) return;
|
|
16420
16331
|
const staleBefore = /* @__PURE__ */ new Date(now.getTime() - LAST_SEEN_WRITE_INTERVAL_MS);
|
|
16421
|
-
if (row.last_used_at === null || row.last_used_at.getTime() < staleBefore.getTime()) await touchLastUsed$1(row.id, now, staleBefore);
|
|
16332
|
+
if (recordUse && (row.last_used_at === null || row.last_used_at.getTime() < staleBefore.getTime())) await touchLastUsed$1(row.id, now, staleBefore, executor);
|
|
16422
16333
|
return {
|
|
16423
16334
|
kind: "token",
|
|
16424
16335
|
tokenId: row.id,
|
|
@@ -17590,7 +17501,7 @@ const editorManifestPlugin = fp(async (app, { manifest }) => {
|
|
|
17590
17501
|
app.decorate("editorManifest", manifest);
|
|
17591
17502
|
}, { name: "shapio-editor-manifest" });
|
|
17592
17503
|
//#endregion
|
|
17593
|
-
//#region src/
|
|
17504
|
+
//#region src/helpers/errorResponse.ts
|
|
17594
17505
|
const STATUS_CODES = {
|
|
17595
17506
|
400: "BAD_REQUEST",
|
|
17596
17507
|
401: "UNAUTHORIZED",
|
|
@@ -17607,6 +17518,10 @@ const STATUS_CODES = {
|
|
|
17607
17518
|
};
|
|
17608
17519
|
/** Errors raised by @fastify/csrf-protection (plugins/csrf.ts). */
|
|
17609
17520
|
const CSRF_ERROR_CODES$1 = /* @__PURE__ */ new Set(["FST_CSRF_INVALID_TOKEN", "FST_CSRF_MISSING_SECRET"]);
|
|
17521
|
+
/**
|
|
17522
|
+
* The one error shape every endpoint returns, `{ error: { code, message, details? } }`, and its status.
|
|
17523
|
+
* Server errors (5xx) never carry their internal text; the caller logs the original error.
|
|
17524
|
+
*/
|
|
17610
17525
|
const toErrorResponse = (error) => {
|
|
17611
17526
|
if (error instanceof AppError) {
|
|
17612
17527
|
const body = { error: {
|
|
@@ -17619,7 +17534,7 @@ const toErrorResponse = (error) => {
|
|
|
17619
17534
|
body
|
|
17620
17535
|
};
|
|
17621
17536
|
}
|
|
17622
|
-
if (CSRF_ERROR_CODES$1.has(error.code)) return {
|
|
17537
|
+
if (error.code !== void 0 && CSRF_ERROR_CODES$1.has(error.code)) return {
|
|
17623
17538
|
statusCode: 403,
|
|
17624
17539
|
body: { error: {
|
|
17625
17540
|
code: "CSRF_INVALID",
|
|
@@ -17654,6 +17569,8 @@ const toErrorResponse = (error) => {
|
|
|
17654
17569
|
} }
|
|
17655
17570
|
};
|
|
17656
17571
|
};
|
|
17572
|
+
//#endregion
|
|
17573
|
+
//#region src/plugins/errorHandler.ts
|
|
17657
17574
|
/** The single error handler: consistent `{ error: { code, message, details? } }` bodies and logging. */
|
|
17658
17575
|
const errorHandlerPlugin = fp(async (app) => {
|
|
17659
17576
|
app.decorateRequest("errorCode", void 0);
|
|
@@ -18223,6 +18140,14 @@ const createMysqlNotificationListener = (options) => {
|
|
|
18223
18140
|
});
|
|
18224
18141
|
};
|
|
18225
18142
|
const connect = async () => {
|
|
18143
|
+
if (closed) return;
|
|
18144
|
+
let mysql;
|
|
18145
|
+
try {
|
|
18146
|
+
mysql = await loadMysql();
|
|
18147
|
+
} catch (error) {
|
|
18148
|
+
log.error({ err: error }, "mysql2 could not be loaded; notifications are off");
|
|
18149
|
+
return;
|
|
18150
|
+
}
|
|
18226
18151
|
if (closed) return;
|
|
18227
18152
|
const current = mysql.createConnection(mysqlPoolOptions(connectionString, 1, options.applicationName ?? "shapio-listen"));
|
|
18228
18153
|
connection = current;
|
|
@@ -18980,6 +18905,45 @@ const createLoaders = (siteId, content) => {
|
|
|
18980
18905
|
};
|
|
18981
18906
|
};
|
|
18982
18907
|
//#endregion
|
|
18908
|
+
//#region src/schema/codegen/graphql/requestContext.ts
|
|
18909
|
+
/**
|
|
18910
|
+
* The context every resolver of one operation receives, with its own DataLoaders. Carries no HTTP objects, so
|
|
18911
|
+
* an operation can run outside a request.
|
|
18912
|
+
*/
|
|
18913
|
+
const createGraphqlContext = ({ site, permissions, isAdmin, content }) => {
|
|
18914
|
+
let base;
|
|
18915
|
+
const contentAt = async (snapshot) => {
|
|
18916
|
+
base ??= content(snapshot);
|
|
18917
|
+
return {
|
|
18918
|
+
...await base,
|
|
18919
|
+
snapshot,
|
|
18920
|
+
permissions
|
|
18921
|
+
};
|
|
18922
|
+
};
|
|
18923
|
+
return {
|
|
18924
|
+
permissions,
|
|
18925
|
+
isAdmin,
|
|
18926
|
+
site,
|
|
18927
|
+
loaders: createLoaders(() => site.id, contentAt),
|
|
18928
|
+
content: contentAt
|
|
18929
|
+
};
|
|
18930
|
+
};
|
|
18931
|
+
//#endregion
|
|
18932
|
+
//#region src/helpers/siteQuery.ts
|
|
18933
|
+
const isSiteSegment = (segment) => {
|
|
18934
|
+
const key = segment.split("=", 1)[0] ?? "";
|
|
18935
|
+
try {
|
|
18936
|
+
return decodeURIComponent(key.replace(/\+/g, " ")) === SITE_QUERY_PARAMETER;
|
|
18937
|
+
} catch {
|
|
18938
|
+
return false;
|
|
18939
|
+
}
|
|
18940
|
+
};
|
|
18941
|
+
/**
|
|
18942
|
+
* A raw querystring (without `?`) without its `site` parameter: site resolution consumes it, and the content
|
|
18943
|
+
* compiler refuses unknown keys. The rest is left exactly as sent (bracket syntax is the compiler's to parse).
|
|
18944
|
+
*/
|
|
18945
|
+
const withoutSiteParameter = (rawQuery) => rawQuery.split("&").filter((segment) => !isSiteSegment(segment)).join("&");
|
|
18946
|
+
//#endregion
|
|
18983
18947
|
//#region src/controllers/contentContext.ts
|
|
18984
18948
|
/**
|
|
18985
18949
|
* The service context for a content request: the pinned snapshot, the principal and dependencies.
|
|
@@ -18987,9 +18951,9 @@ const createLoaders = (siteId, content) => {
|
|
|
18987
18951
|
* memoized per (principal, action, model), so the read, relation visibility, populate and usage recording
|
|
18988
18952
|
* evaluate each model's policy once.
|
|
18989
18953
|
*/
|
|
18990
|
-
const contentContextFor = async (request) => ({
|
|
18954
|
+
const contentContextFor = async (request) => buildContentContext({
|
|
18991
18955
|
db: request.server.db,
|
|
18992
|
-
|
|
18956
|
+
network: await getRequestNetworkSchema(request),
|
|
18993
18957
|
permissions: getRequestPermissions(request),
|
|
18994
18958
|
actor: request.principal,
|
|
18995
18959
|
site: getRequestSite(request),
|
|
@@ -19001,14 +18965,6 @@ const contentContextFor = async (request) => ({
|
|
|
19001
18965
|
requestId: request.id,
|
|
19002
18966
|
ip: request.ip
|
|
19003
18967
|
});
|
|
19004
|
-
const isSiteSegment = (segment) => {
|
|
19005
|
-
const key = segment.split("=", 1)[0] ?? "";
|
|
19006
|
-
try {
|
|
19007
|
-
return decodeURIComponent(key.replace(/\+/g, " ")) === SITE_QUERY_PARAMETER;
|
|
19008
|
-
} catch {
|
|
19009
|
-
return false;
|
|
19010
|
-
}
|
|
19011
|
-
};
|
|
19012
18968
|
/**
|
|
19013
18969
|
* The raw querystring (bracket syntax is parsed by the content compiler, not Fastify's flat parser), without
|
|
19014
18970
|
* `?site=`: site resolution (plugins/siteResolution.ts) consumed it, and the compiler refuses unknown keys.
|
|
@@ -19016,34 +18972,19 @@ const isSiteSegment = (segment) => {
|
|
|
19016
18972
|
const rawQueryOf = (request) => {
|
|
19017
18973
|
const index = request.url.indexOf("?");
|
|
19018
18974
|
if (index === -1) return "";
|
|
19019
|
-
return request.url.slice(index + 1)
|
|
18975
|
+
return withoutSiteParameter(request.url.slice(index + 1));
|
|
19020
18976
|
};
|
|
19021
18977
|
//#endregion
|
|
19022
18978
|
//#region src/controllers/graphqlContext.ts
|
|
19023
18979
|
/** Admin users and admin-scope API tokens: may read drafts. */
|
|
19024
18980
|
const isAdminPrincipal = (principal) => principal.kind === "admin" || principal.kind === "token" && principal.scope === "admin";
|
|
19025
18981
|
/** The context every resolver of one `/api/graphql` request receives (built after site resolution). */
|
|
19026
|
-
const createGraphqlRequestContext = (request) => {
|
|
19027
|
-
|
|
19028
|
-
|
|
19029
|
-
|
|
19030
|
-
|
|
19031
|
-
|
|
19032
|
-
return {
|
|
19033
|
-
...await base,
|
|
19034
|
-
snapshot,
|
|
19035
|
-
permissions
|
|
19036
|
-
};
|
|
19037
|
-
};
|
|
19038
|
-
return {
|
|
19039
|
-
request,
|
|
19040
|
-
permissions,
|
|
19041
|
-
isAdmin: isAdminPrincipal(request.principal),
|
|
19042
|
-
site,
|
|
19043
|
-
loaders: createLoaders(() => site.id, content),
|
|
19044
|
-
content
|
|
19045
|
-
};
|
|
19046
|
-
};
|
|
18982
|
+
const createGraphqlRequestContext = (request) => createGraphqlContext({
|
|
18983
|
+
site: getRequestSite(request),
|
|
18984
|
+
permissions: getRequestPermissions(request),
|
|
18985
|
+
isAdmin: isAdminPrincipal(request.principal),
|
|
18986
|
+
content: () => contentContextFor(request)
|
|
18987
|
+
});
|
|
19047
18988
|
//#endregion
|
|
19048
18989
|
//#region src/controllers/graphql.ts
|
|
19049
18990
|
const introspectionDisabled = () => new AppError(403, "INTROSPECTION_DISABLED", "Schema introspection needs an admin session or an API token (or GRAPHQL_PUBLIC_INTROSPECTION=true)");
|
|
@@ -21548,6 +21489,21 @@ const graphqlPlugin = fp(async (app, { config, urls }) => {
|
|
|
21548
21489
|
]
|
|
21549
21490
|
});
|
|
21550
21491
|
//#endregion
|
|
21492
|
+
//#region src/media/errors.ts
|
|
21493
|
+
/** Thrown by adapters when a key has no object, so callers can tell "missing" from "storage is down". */
|
|
21494
|
+
var ObjectNotFoundError = class extends Error {
|
|
21495
|
+
constructor(key, options) {
|
|
21496
|
+
super(`No stored object at ${key}`, options);
|
|
21497
|
+
this.name = "ObjectNotFoundError";
|
|
21498
|
+
}
|
|
21499
|
+
};
|
|
21500
|
+
var InvalidStorageKeyError = class extends Error {
|
|
21501
|
+
constructor(key) {
|
|
21502
|
+
super(`Not a valid media storage key: ${JSON.stringify(key)}`);
|
|
21503
|
+
this.name = "InvalidStorageKeyError";
|
|
21504
|
+
}
|
|
21505
|
+
};
|
|
21506
|
+
//#endregion
|
|
21551
21507
|
//#region src/media/signing.ts
|
|
21552
21508
|
const sign = (secret, purpose, subject, expiresAt) => createHmac("sha256", secret).update(`${purpose}\n${subject}\n${expiresAt}`).digest("base64url");
|
|
21553
21509
|
const safeEqual = (a, b) => {
|
|
@@ -21665,9 +21621,10 @@ var StorageNotConfiguredError = class extends Error {
|
|
|
21665
21621
|
};
|
|
21666
21622
|
/**
|
|
21667
21623
|
* Every adapter this instance can reach. Local disk is always available; S3 whenever its bucket is set,
|
|
21668
|
-
* whatever STORAGE_DRIVER says, so assets keep being served while `shapio media migrate` moves them.
|
|
21624
|
+
* whatever STORAGE_DRIVER says, so assets keep being served while `shapio media migrate` moves them. The S3
|
|
21625
|
+
* adapter (and the AWS SDK) is loaded only then.
|
|
21669
21626
|
*/
|
|
21670
|
-
const createMediaStorage = (config, deps) => {
|
|
21627
|
+
const createMediaStorage = async (config, deps) => {
|
|
21671
21628
|
const adapters = /* @__PURE__ */ new Map();
|
|
21672
21629
|
adapters.set("local", createLocalAdapter({
|
|
21673
21630
|
root: config.mediaPath,
|
|
@@ -21675,10 +21632,13 @@ const createMediaStorage = (config, deps) => {
|
|
|
21675
21632
|
signingSecret: deps.signingSecret,
|
|
21676
21633
|
publicBaseUrl: config.publicBaseUrl
|
|
21677
21634
|
}));
|
|
21678
|
-
if (config.s3)
|
|
21679
|
-
|
|
21680
|
-
|
|
21681
|
-
|
|
21635
|
+
if (config.s3) {
|
|
21636
|
+
const { createS3Adapter } = await import("./s3Adapter-C8AgFVYw.js");
|
|
21637
|
+
adapters.set("s3", createS3Adapter({
|
|
21638
|
+
config: config.s3,
|
|
21639
|
+
publicBaseUrl: config.publicBaseUrl
|
|
21640
|
+
}));
|
|
21641
|
+
}
|
|
21682
21642
|
const get = (driver) => {
|
|
21683
21643
|
const adapter = adapters.get(driver);
|
|
21684
21644
|
if (!adapter) throw new StorageNotConfiguredError(driver);
|
|
@@ -21694,7 +21654,7 @@ const createMediaStorage = (config, deps) => {
|
|
|
21694
21654
|
//#region src/plugins/mediaStorage.ts
|
|
21695
21655
|
/** Exposes the media storage adapters to routes. Registered after the signing secret is resolved. */
|
|
21696
21656
|
const mediaStoragePlugin = fp(async (app, { storage, urls, signingSecret }) => {
|
|
21697
|
-
app.decorate("mediaStorage", createMediaStorage(storage, {
|
|
21657
|
+
app.decorate("mediaStorage", await createMediaStorage(storage, {
|
|
21698
21658
|
urls,
|
|
21699
21659
|
signingSecret
|
|
21700
21660
|
}));
|
|
@@ -38999,7 +38959,7 @@ const openStoredBundle = (storage, stored) => storage.get(stored.driver).getStre
|
|
|
38999
38959
|
const removeStoredBundle = (storage, stored) => storage.get(stored.driver).delete(stored.key);
|
|
39000
38960
|
//#endregion
|
|
39001
38961
|
//#region src/constants/version.ts
|
|
39002
|
-
const SHAPIO_VERSION = "0.
|
|
38962
|
+
const SHAPIO_VERSION = "0.5.0";
|
|
39003
38963
|
//#endregion
|
|
39004
38964
|
//#region src/repositories/transferExport.ts
|
|
39005
38965
|
/**
|
|
@@ -39791,21 +39751,21 @@ const importContent = async (run, initial) => {
|
|
|
39791
39751
|
});
|
|
39792
39752
|
};
|
|
39793
39753
|
/** Deletes live target entries of the bundle's models that the bundle does not have. */
|
|
39794
|
-
const prune = async (run,
|
|
39754
|
+
const prune = async (run, network) => {
|
|
39795
39755
|
const keep = /* @__PURE__ */ new Set();
|
|
39796
39756
|
const models = /* @__PURE__ */ new Set();
|
|
39797
39757
|
for await (const { record } of readBundle(await open$1(run))) if (record.type === "entry") {
|
|
39798
39758
|
keep.add(record.id);
|
|
39799
39759
|
models.add(record.modelId);
|
|
39800
39760
|
}
|
|
39801
|
-
const context = {
|
|
39761
|
+
const context = buildContentContext({
|
|
39802
39762
|
db: run.deps.db,
|
|
39803
|
-
|
|
39763
|
+
network,
|
|
39804
39764
|
permissions: SYSTEM_PERMISSIONS,
|
|
39805
39765
|
actor: SYSTEM_ACTOR,
|
|
39806
|
-
site: await getSiteRef(run.payload.siteId, run.deps.db)
|
|
39807
|
-
|
|
39808
|
-
};
|
|
39766
|
+
site: await getSiteRef(run.payload.siteId, run.deps.db)
|
|
39767
|
+
});
|
|
39768
|
+
const { snapshot } = context;
|
|
39809
39769
|
let failed = [];
|
|
39810
39770
|
for (let round = 0; round < PRUNE_ROUNDS; round += 1) {
|
|
39811
39771
|
failed = [];
|
|
@@ -39841,7 +39801,7 @@ const runPhase = async (run, phase) => {
|
|
|
39841
39801
|
case "media": return importMedia(run);
|
|
39842
39802
|
case "entries": return importEntryRows(run, await loadSiteSnapshot(run));
|
|
39843
39803
|
case "content": return importContent(run, await loadSiteSnapshot(run));
|
|
39844
|
-
case "prune": return run.payload.prune ? prune(run, await
|
|
39804
|
+
case "prune": return run.payload.prune ? prune(run, await loadSnapshot(run.deps.db)) : void 0;
|
|
39845
39805
|
case "cleanup": return removeStoredBundle(run.deps.storage, run.payload.bundle).catch((error) => run.job.log.warn({
|
|
39846
39806
|
err: describeError(error),
|
|
39847
39807
|
key: run.payload.bundle.key
|
|
@@ -42293,14 +42253,14 @@ const docsRoutes = async (app) => {
|
|
|
42293
42253
|
//#endregion
|
|
42294
42254
|
//#region src/db/migrations/20261001120000_create_platform_tables.ts
|
|
42295
42255
|
var _20261001120000_create_platform_tables_exports = /* @__PURE__ */ __exportAll({
|
|
42296
|
-
down: () => down$
|
|
42297
|
-
up: () => up$
|
|
42256
|
+
down: () => down$34,
|
|
42257
|
+
up: () => up$34
|
|
42298
42258
|
});
|
|
42299
42259
|
/**
|
|
42300
42260
|
* Foundation tables shared by every package: durable versions, the job queue, the transactional outbox
|
|
42301
42261
|
* and the audit log. Statuses are text with CHECK constraints so new states need only a constraint change.
|
|
42302
42262
|
*/
|
|
42303
|
-
const up$
|
|
42263
|
+
const up$34 = async (db) => {
|
|
42304
42264
|
await db.schema.createTable("system_versions").addColumn("id", "boolean", (col) => col.primaryKey().defaultTo(true).check(sql`id`)).addColumn("schema_version", "integer", (col) => col.notNull().defaultTo(0)).addColumn("permissions_version", "integer", (col) => col.notNull().defaultTo(0)).addColumn("updated_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).execute();
|
|
42305
42265
|
await sql`insert into system_versions default values`.execute(db);
|
|
42306
42266
|
await db.schema.createTable("jobs").addColumn("id", "uuid", (col) => col.primaryKey().defaultTo(sql`gen_random_uuid()`)).addColumn("type", "text", (col) => col.notNull()).addColumn("payload", "jsonb", (col) => col.notNull().defaultTo(sql`'{}'::jsonb`)).addColumn("status", "text", (col) => col.notNull().defaultTo("pending").check(sql`status in ('pending', 'running', 'succeeded', 'dead')`)).addColumn("priority", "integer", (col) => col.notNull().defaultTo(0)).addColumn("run_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).addColumn("attempts", "integer", (col) => col.notNull().defaultTo(0)).addColumn("max_attempts", "integer", (col) => col.notNull().defaultTo(10).check(sql`max_attempts > 0`)).addColumn("idempotency_key", "text").addColumn("locked_by", "text").addColumn("locked_until", "timestamptz").addColumn("checkpoint", "jsonb").addColumn("result", "jsonb").addColumn("last_error", "text").addColumn("created_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).addColumn("updated_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).addColumn("finished_at", "timestamptz").execute();
|
|
@@ -42322,7 +42282,7 @@ const up$33 = async (db) => {
|
|
|
42322
42282
|
"occurred_at desc"
|
|
42323
42283
|
]).execute();
|
|
42324
42284
|
};
|
|
42325
|
-
const down$
|
|
42285
|
+
const down$34 = async (db) => {
|
|
42326
42286
|
await db.schema.dropTable("audit_events").execute();
|
|
42327
42287
|
await db.schema.dropTable("outbox_events").execute();
|
|
42328
42288
|
await db.schema.dropTable("jobs").execute();
|
|
@@ -42331,8 +42291,8 @@ const down$33 = async (db) => {
|
|
|
42331
42291
|
//#endregion
|
|
42332
42292
|
//#region src/db/migrations/20261001130000_create_admin_identity.ts
|
|
42333
42293
|
var _20261001130000_create_admin_identity_exports = /* @__PURE__ */ __exportAll({
|
|
42334
|
-
down: () => down$
|
|
42335
|
-
up: () => up$
|
|
42294
|
+
down: () => down$33,
|
|
42295
|
+
up: () => up$33
|
|
42336
42296
|
});
|
|
42337
42297
|
/**
|
|
42338
42298
|
* Admin identity (package B, ADR 0005): admin users, roles and their permission grants, server-side
|
|
@@ -42341,7 +42301,7 @@ var _20261001130000_create_admin_identity_exports = /* @__PURE__ */ __exportAll(
|
|
|
42341
42301
|
*/
|
|
42342
42302
|
const withTimestamps$3 = (table) => table.addColumn("created_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).addColumn("updated_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`));
|
|
42343
42303
|
const uuidPrimaryKey$3 = (table) => table.addColumn("id", "uuid", (col) => col.primaryKey().defaultTo(sql`gen_random_uuid()`));
|
|
42344
|
-
const up$
|
|
42304
|
+
const up$33 = async (db) => {
|
|
42345
42305
|
await withTimestamps$3(uuidPrimaryKey$3(db.schema.createTable("admin_users")).addColumn("email", "text", (col) => col.notNull().unique()).addColumn("name", "text", (col) => col.notNull().defaultTo("")).addColumn("password_hash", "text", (col) => col.notNull()).addColumn("status", "text", (col) => col.notNull().defaultTo("active").check(sql`status in ('active', 'disabled')`)).addColumn("last_login_at", "timestamptz").addColumn("password_changed_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`))).execute();
|
|
42346
42306
|
await withTimestamps$3(uuidPrimaryKey$3(db.schema.createTable("admin_roles")).addColumn("key", "text", (col) => col.notNull().unique().check(sql`key ~ '^[a-z][a-z0-9-]{0,62}$'`)).addColumn("name", "text", (col) => col.notNull()).addColumn("description", "text", (col) => col.notNull().defaultTo("")).addColumn("kind", "text", (col) => col.notNull().defaultTo("admin").check(sql`kind in ('admin', 'delivery')`)).addColumn("is_system", "boolean", (col) => col.notNull().defaultTo(false)).addColumn("version", "integer", (col) => col.notNull().defaultTo(1))).execute();
|
|
42347
42307
|
await withTimestamps$3(uuidPrimaryKey$3(db.schema.createTable("admin_role_permissions")).addColumn("role_id", "uuid", (col) => col.notNull().references("admin_roles.id").onDelete("cascade")).addColumn("action", "text", (col) => col.notNull()).addColumn("model_id", "text").addColumn("condition", "text", (col) => col.check(sql`condition in ('ownedByPrincipal')`)).addColumn("field_ids", sql`text[]`).addUniqueConstraint("admin_role_permissions_grant_uq", [
|
|
@@ -42361,7 +42321,7 @@ const up$32 = async (db) => {
|
|
|
42361
42321
|
await withTimestamps$3(uuidPrimaryKey$3(db.schema.createTable("api_tokens")).addColumn("name", "text", (col) => col.notNull()).addColumn("token_hash", "text", (col) => col.notNull().unique()).addColumn("token_prefix", "text", (col) => col.notNull()).addColumn("role_id", "uuid", (col) => col.notNull().references("admin_roles.id").onDelete("restrict")).addColumn("created_by", "uuid", (col) => col.references("admin_users.id").onDelete("set null")).addColumn("expires_at", "timestamptz").addColumn("last_used_at", "timestamptz").addColumn("revoked_at", "timestamptz")).execute();
|
|
42362
42322
|
await db.schema.createIndex("api_tokens_role_idx").on("api_tokens").column("role_id").execute();
|
|
42363
42323
|
};
|
|
42364
|
-
const down$
|
|
42324
|
+
const down$33 = async (db) => {
|
|
42365
42325
|
await db.schema.dropTable("api_tokens").execute();
|
|
42366
42326
|
await db.schema.dropTable("setup_tokens").execute();
|
|
42367
42327
|
await db.schema.dropTable("password_resets").execute();
|
|
@@ -42375,31 +42335,31 @@ const down$32 = async (db) => {
|
|
|
42375
42335
|
//#endregion
|
|
42376
42336
|
//#region src/db/migrations/20261001130500_create_system_settings.ts
|
|
42377
42337
|
var _20261001130500_create_system_settings_exports = /* @__PURE__ */ __exportAll({
|
|
42378
|
-
down: () => down$
|
|
42379
|
-
up: () => up$
|
|
42338
|
+
down: () => down$32,
|
|
42339
|
+
up: () => up$32
|
|
42380
42340
|
});
|
|
42381
42341
|
/**
|
|
42382
42342
|
* Instance-wide key/value settings that must survive restarts and be shared by every instance, e.g. the
|
|
42383
42343
|
* generated signing secret. General purpose: later packages add keys, not tables.
|
|
42384
42344
|
*/
|
|
42385
|
-
const up$
|
|
42345
|
+
const up$32 = async (db) => {
|
|
42386
42346
|
await db.schema.createTable("system_settings").addColumn("key", "text", (col) => col.primaryKey()).addColumn("value", "text", (col) => col.notNull()).addColumn("updated_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).execute();
|
|
42387
42347
|
};
|
|
42388
|
-
const down$
|
|
42348
|
+
const down$32 = async (db) => {
|
|
42389
42349
|
await db.schema.dropTable("system_settings").execute();
|
|
42390
42350
|
};
|
|
42391
42351
|
//#endregion
|
|
42392
42352
|
//#region src/db/migrations/20261001140000_create_schema_tables.ts
|
|
42393
42353
|
var _20261001140000_create_schema_tables_exports = /* @__PURE__ */ __exportAll({
|
|
42394
|
-
down: () => down$
|
|
42395
|
-
up: () => up$
|
|
42354
|
+
down: () => down$31,
|
|
42355
|
+
up: () => up$31
|
|
42396
42356
|
});
|
|
42397
42357
|
/**
|
|
42398
42358
|
* Schema registry (package D, ADR 0002): models and components (one table, `kind` discriminator), immutable
|
|
42399
42359
|
* schema revisions, the per-model active pointer, schema change jobs, locales and schema settings.
|
|
42400
42360
|
* Model definitions are data: creating or changing a model never runs DDL (CONTRIBUTING.md rule 1).
|
|
42401
42361
|
*/
|
|
42402
|
-
const up$
|
|
42362
|
+
const up$31 = async (db) => {
|
|
42403
42363
|
await db.schema.createTable("models").addColumn("id", "uuid", (col) => col.primaryKey()).addColumn("kind", "text", (col) => col.notNull().check(sql`kind in ('collection', 'singleton', 'component')`)).addColumn("api_key", "text", (col) => col.notNull()).addColumn("created_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).addColumn("updated_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).addColumn("deleted_at", "timestamptz").execute();
|
|
42404
42364
|
await sql`create unique index models_api_key_uq on models (lower(api_key)) where deleted_at is null`.execute(db);
|
|
42405
42365
|
await db.schema.createTable("schema_revisions").addColumn("id", "uuid", (col) => col.primaryKey().defaultTo(sql`gen_random_uuid()`)).addColumn("model_id", "uuid", (col) => col.notNull().references("models.id").onDelete("restrict")).addColumn("version", "integer", (col) => col.notNull().check(sql`version > 0`)).addColumn("definition", "jsonb", (col) => col.notNull()).addColumn("hash", "text", (col) => col.notNull()).addColumn("parent_revision_id", "uuid", (col) => col.references("schema_revisions.id")).addColumn("created_by_type", "text", (col) => col.notNull()).addColumn("created_by_id", "text").addColumn("created_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).addUniqueConstraint("schema_revisions_model_version_uq", ["model_id", "version"]).execute();
|
|
@@ -42427,7 +42387,7 @@ const up$30 = async (db) => {
|
|
|
42427
42387
|
await db.schema.createTable("schema_settings").addColumn("id", "boolean", (col) => col.primaryKey().defaultTo(true).check(sql`id`)).addColumn("read_only", "boolean", (col) => col.notNull().defaultTo(false)).addColumn("read_only_reason", "text").addColumn("updated_by_type", "text").addColumn("updated_by_id", "text").addColumn("updated_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).execute();
|
|
42428
42388
|
await sql`insert into schema_settings default values`.execute(db);
|
|
42429
42389
|
};
|
|
42430
|
-
const down$
|
|
42390
|
+
const down$31 = async (db) => {
|
|
42431
42391
|
await db.schema.dropTable("schema_settings").execute();
|
|
42432
42392
|
await db.schema.dropTable("locales").execute();
|
|
42433
42393
|
await db.schema.dropTable("schema_change_jobs").execute();
|
|
@@ -42439,8 +42399,8 @@ const down$30 = async (db) => {
|
|
|
42439
42399
|
//#endregion
|
|
42440
42400
|
//#region src/db/migrations/20261001150000_create_content_tables.ts
|
|
42441
42401
|
var _20261001150000_create_content_tables_exports = /* @__PURE__ */ __exportAll({
|
|
42442
|
-
down: () => down$
|
|
42443
|
-
up: () => up$
|
|
42402
|
+
down: () => down$30,
|
|
42403
|
+
up: () => up$30
|
|
42444
42404
|
});
|
|
42445
42405
|
/**
|
|
42446
42406
|
* Content storage (package E, ADR 0001): entries, immutable content revisions, mutable heads (one per
|
|
@@ -42448,7 +42408,7 @@ var _20261001150000_create_content_tables_exports = /* @__PURE__ */ __exportAll(
|
|
|
42448
42408
|
* and the publication log behind `?snapshot=N`. User content models never get tables of their own
|
|
42449
42409
|
* (CONTRIBUTING.md rule 1): their values are JSONB keyed by stable field IDs.
|
|
42450
42410
|
*/
|
|
42451
|
-
const up$
|
|
42411
|
+
const up$30 = async (db) => {
|
|
42452
42412
|
await db.schema.createTable("entries").addColumn("id", "uuid", (col) => col.primaryKey().defaultTo(sql`gen_random_uuid()`)).addColumn("model_id", "uuid", (col) => col.notNull().references("models.id").onDelete("restrict")).addColumn("owner_app_user_id", "uuid").addColumn("created_by_admin_id", "uuid", (col) => col.references("admin_users.id").onDelete("set null")).addColumn("created_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).addColumn("updated_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).addColumn("deleted_at", "timestamptz").execute();
|
|
42453
42413
|
await sql`create index entries_model_idx on entries (model_id, created_at) where deleted_at is null`.execute(db);
|
|
42454
42414
|
await sql`create index entries_owner_idx on entries (owner_app_user_id) where owner_app_user_id is not null`.execute(db);
|
|
@@ -42512,7 +42472,7 @@ const up$29 = async (db) => {
|
|
|
42512
42472
|
await sql`create unique index publication_log_open_uq on publication_log (entry_id, locale) where to_seq is null`.execute(db);
|
|
42513
42473
|
await db.schema.createIndex("publication_log_model_seq_idx").on("publication_log").columns(["model_id", "from_seq"]).execute();
|
|
42514
42474
|
};
|
|
42515
|
-
const down$
|
|
42475
|
+
const down$30 = async (db) => {
|
|
42516
42476
|
await db.schema.dropTable("publication_log").execute();
|
|
42517
42477
|
await db.schema.dropTable("publication_state").execute();
|
|
42518
42478
|
await db.schema.dropTable("unique_values").execute();
|
|
@@ -42525,8 +42485,8 @@ const down$29 = async (db) => {
|
|
|
42525
42485
|
//#endregion
|
|
42526
42486
|
//#region src/db/migrations/20261001160000_create_media_tables.ts
|
|
42527
42487
|
var _20261001160000_create_media_tables_exports = /* @__PURE__ */ __exportAll({
|
|
42528
|
-
down: () => down$
|
|
42529
|
-
up: () => up$
|
|
42488
|
+
down: () => down$29,
|
|
42489
|
+
up: () => up$29
|
|
42530
42490
|
});
|
|
42531
42491
|
/**
|
|
42532
42492
|
* Media library (package G): folders, assets, image variants, references from content and upload grants.
|
|
@@ -42537,7 +42497,7 @@ const withTimestamps$2 = (table) => table.addColumn("created_at", "timestamptz",
|
|
|
42537
42497
|
const uuidPrimaryKey$2 = (table) => table.addColumn("id", "uuid", (col) => col.primaryKey().defaultTo(sql`gen_random_uuid()`));
|
|
42538
42498
|
const STORAGE_DRIVER_CHECK = sql`storage_driver in ('local', 's3')`;
|
|
42539
42499
|
const VISIBILITY_CHECK = sql`visibility in ('public', 'private')`;
|
|
42540
|
-
const up$
|
|
42500
|
+
const up$29 = async (db) => {
|
|
42541
42501
|
await withTimestamps$2(uuidPrimaryKey$2(db.schema.createTable("media_folders")).addColumn("parent_id", "uuid", (col) => col.references("media_folders.id").onDelete("restrict")).addColumn("name", "text", (col) => col.notNull().check(sql`length(name) between 1 and 255`)).addColumn("created_by", "uuid", (col) => col.references("admin_users.id").onDelete("set null")).addColumn("version", "integer", (col) => col.notNull().defaultTo(1))).execute();
|
|
42542
42502
|
await sql`create unique index media_folders_sibling_name_uq on media_folders
|
|
42543
42503
|
(coalesce(parent_id, '00000000-0000-0000-0000-000000000000'::uuid), lower(name))`.execute(db);
|
|
@@ -42566,7 +42526,7 @@ const up$28 = async (db) => {
|
|
|
42566
42526
|
]).execute();
|
|
42567
42527
|
await db.schema.createTable("media_upload_grants").addColumn("id", "uuid", (col) => col.primaryKey().defaultTo(sql`gen_random_uuid()`)).addColumn("asset_id", "uuid", (col) => col.notNull()).addColumn("kind", "text", (col) => col.notNull().check(sql`kind in ('create', 'replace')`)).addColumn("storage_driver", "text", (col) => col.notNull().check(STORAGE_DRIVER_CHECK)).addColumn("storage_key", "text", (col) => col.notNull().unique()).addColumn("original_filename", "text", (col) => col.notNull()).addColumn("declared_mime_type", "text", (col) => col.notNull()).addColumn("max_size_bytes", "bigint", (col) => col.notNull()).addColumn("folder_id", "uuid").addColumn("visibility", "text", (col) => col.notNull().check(VISIBILITY_CHECK)).addColumn("created_by", "uuid", (col) => col.references("admin_users.id").onDelete("set null")).addColumn("created_by_principal", "text", (col) => col.notNull()).addColumn("status", "text", (col) => col.notNull().defaultTo("pending").check(sql`status in ('pending', 'consumed', 'rejected', 'expired')`)).addColumn("expires_at", "timestamptz", (col) => col.notNull()).addColumn("consumed_at", "timestamptz").addColumn("created_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).execute();
|
|
42568
42528
|
};
|
|
42569
|
-
const down$
|
|
42529
|
+
const down$29 = async (db) => {
|
|
42570
42530
|
await db.schema.dropTable("media_upload_grants").execute();
|
|
42571
42531
|
await db.schema.dropTable("media_references").execute();
|
|
42572
42532
|
await db.schema.dropTable("media_variants").execute();
|
|
@@ -42576,8 +42536,8 @@ const down$28 = async (db) => {
|
|
|
42576
42536
|
//#endregion
|
|
42577
42537
|
//#region src/db/migrations/20261001170000_create_publishing_tables.ts
|
|
42578
42538
|
var _20261001170000_create_publishing_tables_exports = /* @__PURE__ */ __exportAll({
|
|
42579
|
-
down: () => down$
|
|
42580
|
-
up: () => up$
|
|
42539
|
+
down: () => down$28,
|
|
42540
|
+
up: () => up$28
|
|
42581
42541
|
});
|
|
42582
42542
|
/**
|
|
42583
42543
|
* Publishing (package H): scheduled publications, releases, webhooks and their delivery log, deployment
|
|
@@ -42616,13 +42576,13 @@ const createPreviewTables = async (db) => {
|
|
|
42616
42576
|
await uuidPrimaryKey$1(db.schema.createTable("preview_tokens")).addColumn("token_hash", "text", (col) => col.notNull().unique()).addColumn("token_prefix", "text", (col) => col.notNull()).addColumn("model_id", "uuid", (col) => col.notNull()).addColumn("entry_id", "uuid", (col) => col.references("entries.id").onDelete("cascade")).addColumn("locale", "text").addColumn("connection_id", "uuid", (col) => col.references("deployment_connections.id").onDelete("set null")).addColumn("delivery_role_id", "uuid", (col) => col.references("admin_roles.id").onDelete("set null")).addColumn("created_by", "uuid", (col) => col.notNull().references("admin_users.id").onDelete("cascade")).addColumn("expires_at", "timestamptz", (col) => col.notNull()).addColumn("revoked_at", "timestamptz").addColumn("last_used_at", "timestamptz").addColumn("created_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).execute();
|
|
42617
42577
|
await db.schema.createIndex("preview_tokens_entry_idx").on("preview_tokens").columns(["entry_id", "created_at desc"]).execute();
|
|
42618
42578
|
};
|
|
42619
|
-
const up$
|
|
42579
|
+
const up$28 = async (db) => {
|
|
42620
42580
|
await createSchedulingTables(db);
|
|
42621
42581
|
await createWebhookTables(db);
|
|
42622
42582
|
await createDeploymentTables(db);
|
|
42623
42583
|
await createPreviewTables(db);
|
|
42624
42584
|
};
|
|
42625
|
-
const down$
|
|
42585
|
+
const down$28 = async (db) => {
|
|
42626
42586
|
await db.schema.dropTable("preview_tokens").execute();
|
|
42627
42587
|
await db.schema.dropTable("deployment_runs").execute();
|
|
42628
42588
|
await db.schema.dropTable("deployment_connections").execute();
|
|
@@ -42635,8 +42595,8 @@ const down$27 = async (db) => {
|
|
|
42635
42595
|
//#endregion
|
|
42636
42596
|
//#region src/db/migrations/20261001180000_create_app_users.ts
|
|
42637
42597
|
var _20261001180000_create_app_users_exports = /* @__PURE__ */ __exportAll({
|
|
42638
|
-
down: () => down$
|
|
42639
|
-
up: () => up$
|
|
42598
|
+
down: () => down$27,
|
|
42599
|
+
up: () => up$27
|
|
42640
42600
|
});
|
|
42641
42601
|
/**
|
|
42642
42602
|
* App users (package I, ADR 0005): the end users of sites and apps built on Shapio, with their own roles
|
|
@@ -42687,7 +42647,7 @@ const createCredentials = async (db) => {
|
|
|
42687
42647
|
}
|
|
42688
42648
|
await db.schema.createTable("app_login_codes").addColumn("id", "uuid", (col) => col.primaryKey().defaultTo(sql`gen_random_uuid()`)).addColumn("app_user_id", "uuid", (col) => col.notNull().references("app_users.id").onDelete("cascade")).addColumn("code_hash", "text", (col) => col.notNull().unique()).addColumn("expires_at", "timestamptz", (col) => col.notNull()).addColumn("used_at", "timestamptz").addColumn("created_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).execute();
|
|
42689
42649
|
};
|
|
42690
|
-
const up$
|
|
42650
|
+
const up$27 = async (db) => {
|
|
42691
42651
|
await createUsers(db);
|
|
42692
42652
|
await createRoles(db);
|
|
42693
42653
|
await createCredentials(db);
|
|
@@ -42697,7 +42657,7 @@ const up$26 = async (db) => {
|
|
|
42697
42657
|
foreign key (owner_app_user_id) references app_users (id) on delete set null
|
|
42698
42658
|
`.execute(db);
|
|
42699
42659
|
};
|
|
42700
|
-
const down$
|
|
42660
|
+
const down$27 = async (db) => {
|
|
42701
42661
|
await sql`alter table entries drop constraint if exists entries_owner_app_user_fk`.execute(db);
|
|
42702
42662
|
await db.schema.dropTable("app_login_codes").execute();
|
|
42703
42663
|
await db.schema.dropTable("app_password_resets").execute();
|
|
@@ -42712,8 +42672,8 @@ const down$26 = async (db) => {
|
|
|
42712
42672
|
//#endregion
|
|
42713
42673
|
//#region src/db/migrations/20261002120000_create_extension_hook_runs.ts
|
|
42714
42674
|
var _20261002120000_create_extension_hook_runs_exports = /* @__PURE__ */ __exportAll({
|
|
42715
|
-
down: () => down$
|
|
42716
|
-
up: () => up$
|
|
42675
|
+
down: () => down$26,
|
|
42676
|
+
up: () => up$26
|
|
42717
42677
|
});
|
|
42718
42678
|
/**
|
|
42719
42679
|
* Extension points (package K, ADR 0009): the ledger of post-commit lifecycle hooks (`afterCreate`,
|
|
@@ -42721,17 +42681,17 @@ var _20261002120000_create_extension_hook_runs_exports = /* @__PURE__ */ __expor
|
|
|
42721
42681
|
* as the hook's own database work, so a hook re-run after a worker crash finds its row and is skipped:
|
|
42722
42682
|
* exactly once for everything the hook does through its transaction.
|
|
42723
42683
|
*/
|
|
42724
|
-
const up$
|
|
42684
|
+
const up$26 = async (db) => {
|
|
42725
42685
|
await db.schema.createTable("extension_hook_runs").addColumn("event_id", "uuid", (col) => col.notNull()).addColumn("hook", "text", (col) => col.notNull()).addColumn("job_id", "uuid").addColumn("completed_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).addPrimaryKeyConstraint("extension_hook_runs_pkey", ["event_id", "hook"]).execute();
|
|
42726
42686
|
};
|
|
42727
|
-
const down$
|
|
42687
|
+
const down$26 = async (db) => {
|
|
42728
42688
|
await db.schema.dropTable("extension_hook_runs").execute();
|
|
42729
42689
|
};
|
|
42730
42690
|
//#endregion
|
|
42731
42691
|
//#region src/db/migrations/20261002130000_app_auth_token_version_and_login_code_pkce.ts
|
|
42732
42692
|
var _20261002130000_app_auth_token_version_and_login_code_pkce_exports = /* @__PURE__ */ __exportAll({
|
|
42733
|
-
down: () => down$
|
|
42734
|
-
up: () => up$
|
|
42693
|
+
down: () => down$25,
|
|
42694
|
+
up: () => up$25
|
|
42735
42695
|
});
|
|
42736
42696
|
/**
|
|
42737
42697
|
* App users (ADR 0005):
|
|
@@ -42742,20 +42702,20 @@ var _20261002130000_app_auth_token_version_and_login_code_pkce_exports = /* @__P
|
|
|
42742
42702
|
* sign-in; the one-time login code is only exchanged with the matching verifier. Codes live a minute, so
|
|
42743
42703
|
* any pending ones (issued without a challenge) are dropped rather than given a placeholder.
|
|
42744
42704
|
*/
|
|
42745
|
-
const up$
|
|
42705
|
+
const up$25 = async (db) => {
|
|
42746
42706
|
await db.schema.alterTable("app_users").addColumn("token_version", "integer", (col) => col.notNull().defaultTo(0)).execute();
|
|
42747
42707
|
await sql`delete from app_login_codes`.execute(db);
|
|
42748
42708
|
await db.schema.alterTable("app_login_codes").addColumn("code_challenge", "text", (col) => col.notNull()).execute();
|
|
42749
42709
|
};
|
|
42750
|
-
const down$
|
|
42710
|
+
const down$25 = async (db) => {
|
|
42751
42711
|
await db.schema.alterTable("app_login_codes").dropColumn("code_challenge").execute();
|
|
42752
42712
|
await db.schema.alterTable("app_users").dropColumn("token_version").execute();
|
|
42753
42713
|
};
|
|
42754
42714
|
//#endregion
|
|
42755
42715
|
//#region src/db/migrations/20261002180000_add_publication_log_diff_indexes.ts
|
|
42756
42716
|
var _20261002180000_add_publication_log_diff_indexes_exports = /* @__PURE__ */ __exportAll({
|
|
42757
|
-
down: () => down$
|
|
42758
|
-
up: () => up$
|
|
42717
|
+
down: () => down$24,
|
|
42718
|
+
up: () => up$24
|
|
42759
42719
|
});
|
|
42760
42720
|
/**
|
|
42761
42721
|
* The snapshot diff (repositories/snapshotDiff.ts) finds the (entry, locale) pairs whose live period opened
|
|
@@ -42764,7 +42724,7 @@ var _20261002180000_add_publication_log_diff_indexes_exports = /* @__PURE__ */ _
|
|
|
42764
42724
|
* - `(entry_id, locale, from_seq)`: "the row live at seq N" is the latest row starting at or before N.
|
|
42765
42725
|
* Periods that opened in the range use the existing `(model_id, from_seq)` index.
|
|
42766
42726
|
*/
|
|
42767
|
-
const up$
|
|
42727
|
+
const up$24 = async (db) => {
|
|
42768
42728
|
await sql`create index publication_log_to_seq_idx on publication_log (to_seq) where to_seq is not null`.execute(db);
|
|
42769
42729
|
await db.schema.createIndex("publication_log_entry_locale_from_idx").on("publication_log").columns([
|
|
42770
42730
|
"entry_id",
|
|
@@ -42772,15 +42732,15 @@ const up$23 = async (db) => {
|
|
|
42772
42732
|
"from_seq"
|
|
42773
42733
|
]).execute();
|
|
42774
42734
|
};
|
|
42775
|
-
const down$
|
|
42735
|
+
const down$24 = async (db) => {
|
|
42776
42736
|
await db.schema.dropIndex("publication_log_entry_locale_from_idx").execute();
|
|
42777
42737
|
await db.schema.dropIndex("publication_log_to_seq_idx").execute();
|
|
42778
42738
|
};
|
|
42779
42739
|
//#endregion
|
|
42780
42740
|
//#region src/db/migrations/20261002180100_create_usage_tables.ts
|
|
42781
42741
|
var _20261002180100_create_usage_tables_exports = /* @__PURE__ */ __exportAll({
|
|
42782
|
-
down: () => down$
|
|
42783
|
-
up: () => up$
|
|
42742
|
+
down: () => down$23,
|
|
42743
|
+
up: () => up$23
|
|
42784
42744
|
});
|
|
42785
42745
|
/**
|
|
42786
42746
|
* Field usage from delivery traffic (plan developer-face §5): daily counters written by the in-memory
|
|
@@ -42788,7 +42748,7 @@ var _20261002180100_create_usage_tables_exports = /* @__PURE__ */ __exportAll({
|
|
|
42788
42748
|
* payloads. `principal_key` is `token:<id>`, `app_users` or `anonymous`. Pruned by the retention job
|
|
42789
42749
|
* after USAGE_RETENTION_DAYS.
|
|
42790
42750
|
*/
|
|
42791
|
-
const up$
|
|
42751
|
+
const up$23 = async (db) => {
|
|
42792
42752
|
await db.schema.createTable("field_reads").addColumn("day", "date", (col) => col.notNull()).addColumn("model_id", "uuid", (col) => col.notNull()).addColumn("field_path", "text", (col) => col.notNull()).addColumn("principal_key", "text", (col) => col.notNull()).addColumn("selection", "text", (col) => col.notNull().check(sql`selection in ('explicit', 'implicit')`)).addColumn("reads", "bigint", (col) => col.notNull().defaultTo(0)).addColumn("last_read_at", "timestamptz", (col) => col.notNull()).addPrimaryKeyConstraint("field_reads_pkey", [
|
|
42793
42753
|
"day",
|
|
42794
42754
|
"model_id",
|
|
@@ -42799,15 +42759,15 @@ const up$22 = async (db) => {
|
|
|
42799
42759
|
await db.schema.createIndex("field_reads_model_day_idx").on("field_reads").columns(["model_id", "day"]).execute();
|
|
42800
42760
|
await db.schema.createTable("token_reads").addColumn("day", "date", (col) => col.notNull()).addColumn("principal_key", "text", (col) => col.notNull()).addColumn("requests", "bigint", (col) => col.notNull().defaultTo(0)).addColumn("last_snapshot", "bigint").addColumn("last_read_at", "timestamptz", (col) => col.notNull()).addPrimaryKeyConstraint("token_reads_pkey", ["day", "principal_key"]).execute();
|
|
42801
42761
|
};
|
|
42802
|
-
const down$
|
|
42762
|
+
const down$23 = async (db) => {
|
|
42803
42763
|
await db.schema.dropTable("token_reads").execute();
|
|
42804
42764
|
await db.schema.dropTable("field_reads").execute();
|
|
42805
42765
|
};
|
|
42806
42766
|
//#endregion
|
|
42807
42767
|
//#region src/db/migrations/20261002180200_create_change_sets.ts
|
|
42808
42768
|
var _20261002180200_create_change_sets_exports = /* @__PURE__ */ __exportAll({
|
|
42809
|
-
down: () => down$
|
|
42810
|
-
up: () => up$
|
|
42769
|
+
down: () => down$22,
|
|
42770
|
+
up: () => up$22
|
|
42811
42771
|
});
|
|
42812
42772
|
/**
|
|
42813
42773
|
* Change sets (developer-face plan §5, ADR 0010): schema drafts and entry publications that ship as ONE
|
|
@@ -42986,7 +42946,7 @@ const migrateReleases = async (db) => {
|
|
|
42986
42946
|
await sql`drop table release_items`.execute(db);
|
|
42987
42947
|
await sql`drop table releases`.execute(db);
|
|
42988
42948
|
};
|
|
42989
|
-
const up$
|
|
42949
|
+
const up$22 = async (db) => {
|
|
42990
42950
|
await createTables(db);
|
|
42991
42951
|
await linkExecutionRecords(db);
|
|
42992
42952
|
await allowConversionRevisions(db);
|
|
@@ -43058,7 +43018,7 @@ const restoreReleases = async (db) => {
|
|
|
43058
43018
|
await sql`update webhooks set events = array_remove(array_remove(events, 'change_set.shipping'),
|
|
43059
43019
|
'change_set.discarded')`.execute(db);
|
|
43060
43020
|
};
|
|
43061
|
-
const down$
|
|
43021
|
+
const down$22 = async (db) => {
|
|
43062
43022
|
await restoreReleases(db);
|
|
43063
43023
|
await sql`alter table content_revisions drop constraint content_revisions_reason_check`.execute(db);
|
|
43064
43024
|
await sql`alter table content_revisions add constraint content_revisions_reason_check
|
|
@@ -43079,8 +43039,8 @@ const down$21 = async (db) => {
|
|
|
43079
43039
|
//#endregion
|
|
43080
43040
|
//#region src/db/migrations/20261002190000_create_editor_presence_and_content_health.ts
|
|
43081
43041
|
var _20261002190000_create_editor_presence_and_content_health_exports = /* @__PURE__ */ __exportAll({
|
|
43082
|
-
down: () => down$
|
|
43083
|
-
up: () => up$
|
|
43042
|
+
down: () => down$21,
|
|
43043
|
+
up: () => up$21
|
|
43084
43044
|
});
|
|
43085
43045
|
/**
|
|
43086
43046
|
* Editor experience (plan editor-experience §9):
|
|
@@ -43091,7 +43051,7 @@ var _20261002190000_create_editor_presence_and_content_health_exports = /* @__PU
|
|
|
43091
43051
|
* - `content_health_findings`: open and recently resolved findings of the health rules per entry and
|
|
43092
43052
|
* locale (`*` for the entry as a whole). An evaluation upserts what it found and resolves the rest.
|
|
43093
43053
|
*/
|
|
43094
|
-
const up$
|
|
43054
|
+
const up$21 = async (db) => {
|
|
43095
43055
|
await sql`
|
|
43096
43056
|
create unlogged table editor_presence (
|
|
43097
43057
|
entry_id uuid not null,
|
|
@@ -43128,15 +43088,15 @@ const up$20 = async (db) => {
|
|
|
43128
43088
|
await sql`create index content_health_findings_resolved_idx on content_health_findings (resolved_at)
|
|
43129
43089
|
where resolved_at is not null`.execute(db);
|
|
43130
43090
|
};
|
|
43131
|
-
const down$
|
|
43091
|
+
const down$21 = async (db) => {
|
|
43132
43092
|
await sql`drop table content_health_findings`.execute(db);
|
|
43133
43093
|
await sql`drop table editor_presence`.execute(db);
|
|
43134
43094
|
};
|
|
43135
43095
|
//#endregion
|
|
43136
43096
|
//#region src/db/migrations/20261003120000_add_changes_ship_permission.ts
|
|
43137
43097
|
var _20261003120000_add_changes_ship_permission_exports = /* @__PURE__ */ __exportAll({
|
|
43138
|
-
down: () => down$
|
|
43139
|
-
up: () => up$
|
|
43098
|
+
down: () => down$20,
|
|
43099
|
+
up: () => up$20
|
|
43140
43100
|
});
|
|
43141
43101
|
/**
|
|
43142
43102
|
* `changes.ship` (agentic plan §I): shipping a change set (and scheduling a ship) becomes its own global
|
|
@@ -43144,7 +43104,7 @@ var _20261003120000_add_changes_ship_permission_exports = /* @__PURE__ */ __expo
|
|
|
43144
43104
|
* live. Every role that holds `changes.manage` today keeps what it could do: it gets `changes.ship` too.
|
|
43145
43105
|
* The permissions version moves only when grants changed, so running instances reload exactly then.
|
|
43146
43106
|
*/
|
|
43147
|
-
const up$
|
|
43107
|
+
const up$20 = async (db) => {
|
|
43148
43108
|
await sql`
|
|
43149
43109
|
with granted as (
|
|
43150
43110
|
insert into admin_role_permissions (role_id, action, model_id, condition, field_ids)
|
|
@@ -43158,7 +43118,7 @@ const up$19 = async (db) => {
|
|
|
43158
43118
|
where exists (select 1 from granted)
|
|
43159
43119
|
`.execute(db);
|
|
43160
43120
|
};
|
|
43161
|
-
const down$
|
|
43121
|
+
const down$20 = async (db) => {
|
|
43162
43122
|
await sql`
|
|
43163
43123
|
with revoked as (
|
|
43164
43124
|
delete from admin_role_permissions where action = 'changes.ship' returning 1
|
|
@@ -43170,8 +43130,8 @@ const down$19 = async (db) => {
|
|
|
43170
43130
|
//#endregion
|
|
43171
43131
|
//#region src/db/migrations/20261003130000_create_sites.ts
|
|
43172
43132
|
var _20261003130000_create_sites_exports = /* @__PURE__ */ __exportAll({
|
|
43173
|
-
down: () => down$
|
|
43174
|
-
up: () => up$
|
|
43133
|
+
down: () => down$19,
|
|
43134
|
+
up: () => up$19
|
|
43175
43135
|
});
|
|
43176
43136
|
/**
|
|
43177
43137
|
* Sites (plan agentic-ecosystem §H, ADR 0011): one instance hosts many sites with one schema and one login.
|
|
@@ -43359,7 +43319,7 @@ const siteRoleAssignments = async (db) => {
|
|
|
43359
43319
|
`.execute(db);
|
|
43360
43320
|
await sql`alter table admin_invitations drop column role_ids`.execute(db);
|
|
43361
43321
|
};
|
|
43362
|
-
const up$
|
|
43322
|
+
const up$19 = async (db) => {
|
|
43363
43323
|
await createSites(db);
|
|
43364
43324
|
await addSiteColumns(db);
|
|
43365
43325
|
await tieCopiesToEntries(db);
|
|
@@ -43372,7 +43332,7 @@ const assertSingleSite = async (db) => {
|
|
|
43372
43332
|
const { rows } = await sql`select count(*)::text as count from sites`.execute(db);
|
|
43373
43333
|
if (Number(rows[0]?.count ?? 0) > 1) throw new Error("Cannot roll back sites while more than one site exists: merging them would merge their snapshot ledgers and uniqueness and widen role assignments. Delete the other sites first.");
|
|
43374
43334
|
};
|
|
43375
|
-
const down$
|
|
43335
|
+
const down$19 = async (db) => {
|
|
43376
43336
|
await assertSingleSite(db);
|
|
43377
43337
|
await sql`alter table admin_invitations add column role_ids uuid[] not null default '{}'::uuid[]`.execute(db);
|
|
43378
43338
|
await sql`
|
|
@@ -43443,8 +43403,8 @@ const down$18 = async (db) => {
|
|
|
43443
43403
|
//#endregion
|
|
43444
43404
|
//#region src/db/migrations/20261003140200_enqueue_field_index_layout.ts
|
|
43445
43405
|
var _20261003140200_enqueue_field_index_layout_exports = /* @__PURE__ */ __exportAll({
|
|
43446
|
-
down: () => down$
|
|
43447
|
-
up: () => up$
|
|
43406
|
+
down: () => down$18,
|
|
43407
|
+
up: () => up$18
|
|
43448
43408
|
});
|
|
43449
43409
|
/**
|
|
43450
43410
|
* Field index layout v2 (sites plan §H): per-field expression indexes on `entry_heads` lead with `site_id`,
|
|
@@ -43456,7 +43416,7 @@ var _20261003140200_enqueue_field_index_layout_exports = /* @__PURE__ */ __expor
|
|
|
43456
43416
|
*/
|
|
43457
43417
|
const JOB_TYPE$1 = "schema.fieldIndexLayout";
|
|
43458
43418
|
const IDEMPOTENCY_KEY$1 = "schema.fieldIndexLayout:v2";
|
|
43459
|
-
const up$
|
|
43419
|
+
const up$18 = async (db) => {
|
|
43460
43420
|
await sql`
|
|
43461
43421
|
insert into jobs (type, payload, max_attempts, idempotency_key)
|
|
43462
43422
|
select ${JOB_TYPE$1}, '{}'::jsonb, 5, ${IDEMPOTENCY_KEY$1}
|
|
@@ -43469,14 +43429,14 @@ const up$17 = async (db) => {
|
|
|
43469
43429
|
`.execute(db);
|
|
43470
43430
|
};
|
|
43471
43431
|
/** The layout job is idempotent; rolling back only forgets it if it has not run yet. */
|
|
43472
|
-
const down$
|
|
43432
|
+
const down$18 = async (db) => {
|
|
43473
43433
|
await sql`delete from jobs where idempotency_key = ${IDEMPOTENCY_KEY$1} and status = 'pending'`.execute(db);
|
|
43474
43434
|
};
|
|
43475
43435
|
//#endregion
|
|
43476
43436
|
//#region src/db/migrations/20261003140500_change_set_items_site_and_preview_entry.ts
|
|
43477
43437
|
var _20261003140500_change_set_items_site_and_preview_entry_exports = /* @__PURE__ */ __exportAll({
|
|
43478
|
-
down: () => down$
|
|
43479
|
-
up: () => up$
|
|
43438
|
+
down: () => down$17,
|
|
43439
|
+
up: () => up$17
|
|
43480
43440
|
});
|
|
43481
43441
|
/**
|
|
43482
43442
|
* Sites, publishing (plan agentic-ecosystem §H, package G5).
|
|
@@ -43487,7 +43447,7 @@ var _20261003140500_change_set_items_site_and_preview_entry_exports = /* @__PURE
|
|
|
43487
43447
|
* - `preview_tokens.entry_id` becomes required: a preview token previews one entry of one site. Model-wide
|
|
43488
43448
|
* tokens (short-lived by design) are deleted; whoever needs one opens the entry's preview again.
|
|
43489
43449
|
*/
|
|
43490
|
-
const up$
|
|
43450
|
+
const up$17 = async (db) => {
|
|
43491
43451
|
await sql`alter table change_sets add constraint change_sets_id_site_uq unique (id, site_id)`.execute(db);
|
|
43492
43452
|
await sql`alter table change_set_items add column site_id uuid`.execute(db);
|
|
43493
43453
|
await sql`
|
|
@@ -43503,7 +43463,7 @@ const up$16 = async (db) => {
|
|
|
43503
43463
|
await sql`delete from preview_tokens where entry_id is null`.execute(db);
|
|
43504
43464
|
await sql`alter table preview_tokens alter column entry_id set not null`.execute(db);
|
|
43505
43465
|
};
|
|
43506
|
-
const down$
|
|
43466
|
+
const down$17 = async (db) => {
|
|
43507
43467
|
await sql`alter table preview_tokens alter column entry_id drop not null`.execute(db);
|
|
43508
43468
|
await sql`alter table change_set_items drop constraint change_set_items_entry_site_fk`.execute(db);
|
|
43509
43469
|
await sql`alter table change_set_items drop constraint change_set_items_set_site_fk`.execute(db);
|
|
@@ -43513,8 +43473,8 @@ const down$16 = async (db) => {
|
|
|
43513
43473
|
//#endregion
|
|
43514
43474
|
//#region src/db/migrations/20261003150000_widen_deployment_providers.ts
|
|
43515
43475
|
var _20261003150000_widen_deployment_providers_exports = /* @__PURE__ */ __exportAll({
|
|
43516
|
-
down: () => down$
|
|
43517
|
-
up: () => up$
|
|
43476
|
+
down: () => down$16,
|
|
43477
|
+
up: () => up$16
|
|
43518
43478
|
});
|
|
43519
43479
|
/**
|
|
43520
43480
|
* Deploy adapters (plan agentic-ecosystem §B2): deployment connections may use the Vercel and Netlify
|
|
@@ -43529,11 +43489,11 @@ const replaceCheck = async (db, check) => {
|
|
|
43529
43489
|
check (${check}) not valid`.execute(db);
|
|
43530
43490
|
await sql`alter table deployment_connections validate constraint deployment_connections_provider_check`.execute(db);
|
|
43531
43491
|
};
|
|
43532
|
-
const up$
|
|
43492
|
+
const up$16 = async (db) => {
|
|
43533
43493
|
await replaceCheck(db, WIDENED);
|
|
43534
43494
|
};
|
|
43535
43495
|
/** Refuses while Vercel or Netlify connections exist: a down migration never deletes user data. */
|
|
43536
|
-
const down$
|
|
43496
|
+
const down$16 = async (db) => {
|
|
43537
43497
|
const { rows } = await sql`
|
|
43538
43498
|
select count(*)::text as count from deployment_connections where provider in ('vercel', 'netlify')
|
|
43539
43499
|
`.execute(db);
|
|
@@ -43544,8 +43504,8 @@ const down$15 = async (db) => {
|
|
|
43544
43504
|
//#endregion
|
|
43545
43505
|
//#region src/db/migrations/20261003160000_create_assist_runs.ts
|
|
43546
43506
|
var _20261003160000_create_assist_runs_exports = /* @__PURE__ */ __exportAll({
|
|
43547
|
-
down: () => down$
|
|
43548
|
-
up: () => up$
|
|
43507
|
+
down: () => down$15,
|
|
43508
|
+
up: () => up$15
|
|
43549
43509
|
});
|
|
43550
43510
|
/**
|
|
43551
43511
|
* Editor assists (plan agentic-ecosystem §A0, §I): one `assist_runs` row per assist request (who, which
|
|
@@ -43561,14 +43521,14 @@ const replaceSourceCheck = async (db, check) => {
|
|
|
43561
43521
|
await sql`alter table change_sets add constraint change_sets_source_check check (${check}) not valid`.execute(db);
|
|
43562
43522
|
await sql`alter table change_sets validate constraint change_sets_source_check`.execute(db);
|
|
43563
43523
|
};
|
|
43564
|
-
const up$
|
|
43524
|
+
const up$15 = async (db) => {
|
|
43565
43525
|
await db.schema.createTable("assist_runs").addColumn("id", "uuid", (col) => col.primaryKey().defaultTo(sql`gen_random_uuid()`)).addColumn("site_id", "uuid", (col) => col.notNull().references("sites.id").onDelete("cascade")).addColumn("actor_type", "text", (col) => col.notNull()).addColumn("actor_id", "text", (col) => col.notNull()).addColumn("action", "text", (col) => col.notNull().check(ACTIONS)).addColumn("rule", "text").addColumn("provider", "text", (col) => col.notNull()).addColumn("model", "text", (col) => col.notNull()).addColumn("input_tokens", "integer", (col) => col.notNull().defaultTo(0)).addColumn("output_tokens", "integer", (col) => col.notNull().defaultTo(0)).addColumn("duration_ms", "integer", (col) => col.notNull().defaultTo(0)).addColumn("status", "text", (col) => col.notNull().check(sql`status in ('queued', 'running', 'succeeded', 'failed')`)).addColumn("error_code", "text").addColumn("job_id", "uuid", (col) => col.references("jobs.id").onDelete("set null")).addColumn("created_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).addColumn("finished_at", "timestamptz").execute();
|
|
43566
43526
|
await db.schema.createIndex("assist_runs_site_created_idx").on("assist_runs").columns(["site_id", "created_at"]).execute();
|
|
43567
43527
|
await db.schema.createIndex("assist_runs_created_idx").on("assist_runs").column("created_at").execute();
|
|
43568
43528
|
await replaceSourceCheck(db, SOURCES_WIDENED);
|
|
43569
43529
|
};
|
|
43570
43530
|
/** Refuses while change sets opened by assist exist: a down migration never deletes user data. */
|
|
43571
|
-
const down$
|
|
43531
|
+
const down$15 = async (db) => {
|
|
43572
43532
|
const { rows } = await sql`
|
|
43573
43533
|
select count(*)::text as count from change_sets where source = 'assist'
|
|
43574
43534
|
`.execute(db);
|
|
@@ -43580,8 +43540,8 @@ const down$14 = async (db) => {
|
|
|
43580
43540
|
//#endregion
|
|
43581
43541
|
//#region src/db/migrations/20261003170000_audit_events_seq.ts
|
|
43582
43542
|
var _20261003170000_audit_events_seq_exports$2 = /* @__PURE__ */ __exportAll({
|
|
43583
|
-
down: () => down$
|
|
43584
|
-
up: () => up$
|
|
43543
|
+
down: () => down$14,
|
|
43544
|
+
up: () => up$14
|
|
43585
43545
|
});
|
|
43586
43546
|
/**
|
|
43587
43547
|
* `audit_events.seq`: a monotonic tiebreaker after `occurred_at`, so events written in the same instant (one
|
|
@@ -43590,17 +43550,17 @@ var _20261003170000_audit_events_seq_exports$2 = /* @__PURE__ */ __exportAll({
|
|
|
43590
43550
|
* are numbered in the order the rewrite reads them. No index: the audit queries filter and sort by
|
|
43591
43551
|
* `occurred_at` first, and `seq` only breaks ties.
|
|
43592
43552
|
*/
|
|
43593
|
-
const up$
|
|
43553
|
+
const up$14 = async (db) => {
|
|
43594
43554
|
await db.schema.alterTable("audit_events").addColumn("seq", "bigint", (col) => col.notNull().generatedAlwaysAsIdentity()).execute();
|
|
43595
43555
|
};
|
|
43596
|
-
const down$
|
|
43556
|
+
const down$14 = async (db) => {
|
|
43597
43557
|
await db.schema.alterTable("audit_events").dropColumn("seq").execute();
|
|
43598
43558
|
};
|
|
43599
43559
|
//#endregion
|
|
43600
43560
|
//#region src/db/migrations/20261004120000_models_site_scope.ts
|
|
43601
43561
|
var _20261004120000_models_site_scope_exports$2 = /* @__PURE__ */ __exportAll({
|
|
43602
|
-
down: () => down$
|
|
43603
|
-
up: () => up$
|
|
43562
|
+
down: () => down$13,
|
|
43563
|
+
up: () => up$13
|
|
43604
43564
|
});
|
|
43605
43565
|
/**
|
|
43606
43566
|
* Per-site schema (plan site-schema): a definition belongs to one site (`models.site_id`) or is shared by every
|
|
@@ -43613,7 +43573,7 @@ var _20261004120000_models_site_scope_exports$2 = /* @__PURE__ */ __exportAll({
|
|
|
43613
43573
|
* over `lower(api_key)` cannot hold. Share or delete them first; then `down` is lossless.
|
|
43614
43574
|
*/
|
|
43615
43575
|
const NIL_UUID$1 = "00000000-0000-0000-0000-000000000000";
|
|
43616
|
-
const up$
|
|
43576
|
+
const up$13 = async (db) => {
|
|
43617
43577
|
await sql`alter table models add column site_id uuid references sites (id)`.execute(db);
|
|
43618
43578
|
await sql`create index models_site_idx on models (site_id)`.execute(db);
|
|
43619
43579
|
await sql`drop index models_api_key_uq`.execute(db);
|
|
@@ -43623,7 +43583,7 @@ const up$12 = async (db) => {
|
|
|
43623
43583
|
`.execute(db);
|
|
43624
43584
|
await sql`alter table schema_drafts add column shared boolean not null default false`.execute(db);
|
|
43625
43585
|
};
|
|
43626
|
-
const down$
|
|
43586
|
+
const down$13 = async (db) => {
|
|
43627
43587
|
const { rows } = await sql`select count(*)::text as count from models where site_id is not null`.execute(db);
|
|
43628
43588
|
if (Number(rows[0]?.count ?? 0) > 0) throw new Error("Cannot roll back per-site schema while definitions belong to a site: two sites may share an API ID. Share or delete the site definitions first.");
|
|
43629
43589
|
await sql`alter table schema_drafts drop column shared`.execute(db);
|
|
@@ -43635,8 +43595,8 @@ const down$12 = async (db) => {
|
|
|
43635
43595
|
//#endregion
|
|
43636
43596
|
//#region src/db/migrations/20261004130000_site_seo_settings.ts
|
|
43637
43597
|
var _20261004130000_site_seo_settings_exports$2 = /* @__PURE__ */ __exportAll({
|
|
43638
|
-
down: () => down$
|
|
43639
|
-
up: () => up$
|
|
43598
|
+
down: () => down$12,
|
|
43599
|
+
up: () => up$12
|
|
43640
43600
|
});
|
|
43641
43601
|
/**
|
|
43642
43602
|
* SEO defaults per site (plan seo-fields): `sites.seo_defaults` holds the site's default texts per locale, its
|
|
@@ -43647,7 +43607,7 @@ var _20261004130000_site_seo_settings_exports$2 = /* @__PURE__ */ __exportAll({
|
|
|
43647
43607
|
* about what a site publishes) gets it; the built-in owner and admin roles get it from `ensureSystemRoles`.
|
|
43648
43608
|
* The permissions version moves only when grants changed, so running instances reload exactly then.
|
|
43649
43609
|
*/
|
|
43650
|
-
const up$
|
|
43610
|
+
const up$12 = async (db) => {
|
|
43651
43611
|
await sql`alter table sites add column seo_defaults jsonb`.execute(db);
|
|
43652
43612
|
await sql`
|
|
43653
43613
|
with granted as (
|
|
@@ -43662,7 +43622,7 @@ const up$11 = async (db) => {
|
|
|
43662
43622
|
where exists (select 1 from granted)
|
|
43663
43623
|
`.execute(db);
|
|
43664
43624
|
};
|
|
43665
|
-
const down$
|
|
43625
|
+
const down$12 = async (db) => {
|
|
43666
43626
|
await sql`
|
|
43667
43627
|
with revoked as (
|
|
43668
43628
|
delete from admin_role_permissions where action = 'site.settings' returning 1
|
|
@@ -43675,8 +43635,8 @@ const down$11 = async (db) => {
|
|
|
43675
43635
|
//#endregion
|
|
43676
43636
|
//#region src/db/migrations/20261005120000_entry_heads_entry_created_at.ts
|
|
43677
43637
|
var _20261005120000_entry_heads_entry_created_at_exports$2 = /* @__PURE__ */ __exportAll({
|
|
43678
|
-
down: () => down$
|
|
43679
|
-
up: () => up$
|
|
43638
|
+
down: () => down$11,
|
|
43639
|
+
up: () => up$11
|
|
43680
43640
|
});
|
|
43681
43641
|
/**
|
|
43682
43642
|
* Delivery perf 2 (ADR 0001 amendment): the entry's `created_at` on each head (`entry_created_at`), so a list
|
|
@@ -43693,7 +43653,7 @@ const INDEX$2 = "entry_heads_entry_order_idx";
|
|
|
43693
43653
|
const JOB_TYPE = "schema.entryOrderIndex";
|
|
43694
43654
|
const IDEMPOTENCY_KEY = "schema.entryOrderIndex:v1";
|
|
43695
43655
|
const BATCH$1 = 5e3;
|
|
43696
|
-
const up$
|
|
43656
|
+
const up$11 = async (db) => {
|
|
43697
43657
|
await sql`alter table entry_heads add column entry_created_at timestamptz`.execute(db);
|
|
43698
43658
|
for (;;) {
|
|
43699
43659
|
const result = await sql`
|
|
@@ -43718,12 +43678,25 @@ const up$10 = async (db) => {
|
|
|
43718
43678
|
create index ${sql.id(INDEX$2)} on entry_heads (site_id, model_id, state, entry_created_at desc, entry_id)
|
|
43719
43679
|
`.execute(db);
|
|
43720
43680
|
};
|
|
43721
|
-
const down$
|
|
43681
|
+
const down$11 = async (db) => {
|
|
43722
43682
|
await sql`delete from jobs where idempotency_key = ${IDEMPOTENCY_KEY} and status = 'pending'`.execute(db);
|
|
43723
43683
|
await sql`drop index if exists ${sql.id(INDEX$2)}`.execute(db);
|
|
43724
43684
|
await sql`alter table entry_heads drop column entry_created_at`.execute(db);
|
|
43725
43685
|
};
|
|
43726
43686
|
//#endregion
|
|
43687
|
+
//#region src/db/migrations/20261006120000_system_versions_release.ts
|
|
43688
|
+
var _20261006120000_system_versions_release_exports = /* @__PURE__ */ __exportAll({
|
|
43689
|
+
dialectNeutral: () => true,
|
|
43690
|
+
down: () => down$10,
|
|
43691
|
+
up: () => up$10
|
|
43692
|
+
});
|
|
43693
|
+
const up$10 = async (db) => {
|
|
43694
|
+
await db.schema.alterTable("system_versions").addColumn("release", "text").execute();
|
|
43695
|
+
};
|
|
43696
|
+
const down$10 = async (db) => {
|
|
43697
|
+
await db.schema.alterTable("system_versions").dropColumn("release").execute();
|
|
43698
|
+
};
|
|
43699
|
+
//#endregion
|
|
43727
43700
|
//#region src/db/migrations/mysql/0001_baseline.ts
|
|
43728
43701
|
var _0001_baseline_exports$1 = /* @__PURE__ */ __exportAll({
|
|
43729
43702
|
down: () => down$9,
|
|
@@ -45025,7 +44998,8 @@ const MYSQL_MIGRATIONS = {
|
|
|
45025
44998
|
"20261003170000_audit_events_seq": _20261003170000_audit_events_seq_exports$1,
|
|
45026
44999
|
"20261004120000_models_site_scope": _20261004120000_models_site_scope_exports$1,
|
|
45027
45000
|
"20261004130000_site_seo_settings": _20261004130000_site_seo_settings_exports$1,
|
|
45028
|
-
"20261005120000_entry_heads_entry_created_at": _20261005120000_entry_heads_entry_created_at_exports$1
|
|
45001
|
+
"20261005120000_entry_heads_entry_created_at": _20261005120000_entry_heads_entry_created_at_exports$1,
|
|
45002
|
+
"20261006120000_system_versions_release": _20261006120000_system_versions_release_exports
|
|
45029
45003
|
};
|
|
45030
45004
|
//#endregion
|
|
45031
45005
|
//#region src/db/migrations/sqlite/0001_baseline.ts
|
|
@@ -46348,7 +46322,8 @@ const SQLITE_MIGRATIONS = {
|
|
|
46348
46322
|
"20261003170000_audit_events_seq": _20261003170000_audit_events_seq_exports,
|
|
46349
46323
|
"20261004120000_models_site_scope": _20261004120000_models_site_scope_exports,
|
|
46350
46324
|
"20261004130000_site_seo_settings": _20261004130000_site_seo_settings_exports,
|
|
46351
|
-
"20261005120000_entry_heads_entry_created_at": _20261005120000_entry_heads_entry_created_at_exports
|
|
46325
|
+
"20261005120000_entry_heads_entry_created_at": _20261005120000_entry_heads_entry_created_at_exports,
|
|
46326
|
+
"20261006120000_system_versions_release": _20261006120000_system_versions_release_exports
|
|
46352
46327
|
};
|
|
46353
46328
|
//#endregion
|
|
46354
46329
|
//#region src/db/migrations/index.ts
|
|
@@ -46381,7 +46356,8 @@ const MIGRATIONS = {
|
|
|
46381
46356
|
"20261003170000_audit_events_seq": _20261003170000_audit_events_seq_exports$2,
|
|
46382
46357
|
"20261004120000_models_site_scope": _20261004120000_models_site_scope_exports$2,
|
|
46383
46358
|
"20261004130000_site_seo_settings": _20261004130000_site_seo_settings_exports$2,
|
|
46384
|
-
"20261005120000_entry_heads_entry_created_at": _20261005120000_entry_heads_entry_created_at_exports$2
|
|
46359
|
+
"20261005120000_entry_heads_entry_created_at": _20261005120000_entry_heads_entry_created_at_exports$2,
|
|
46360
|
+
"20261006120000_system_versions_release": _20261006120000_system_versions_release_exports
|
|
46385
46361
|
};
|
|
46386
46362
|
const PROVIDERS = {
|
|
46387
46363
|
postgres: { getMigrations: () => Promise.resolve({ ...MIGRATIONS }) },
|
|
@@ -46684,6 +46660,24 @@ const parseByteRange = (header, size) => {
|
|
|
46684
46660
|
};
|
|
46685
46661
|
};
|
|
46686
46662
|
//#endregion
|
|
46663
|
+
//#region src/media/contentDisposition.ts
|
|
46664
|
+
/**
|
|
46665
|
+
* A Content-Disposition value that names the file safely: an ASCII fallback plus the RFC 5987 UTF-8 form,
|
|
46666
|
+
* so quotes, semicolons or line breaks in a filename can never inject header parameters.
|
|
46667
|
+
*/
|
|
46668
|
+
const contentDisposition = (filename, type = "inline") => {
|
|
46669
|
+
return `${type}; filename="${filename.replace(/[^\x20-\x7e]/g, "_").replace(/["\\]/g, "_")}"; filename*=UTF-8''${encodeURIComponent(filename)}`;
|
|
46670
|
+
};
|
|
46671
|
+
/** Types a browser only ever displays passively: opening one directly cannot run script. */
|
|
46672
|
+
const PASSIVE_INLINE_TYPE = /^(image\/(png|jpeg|gif|webp|avif|bmp|tiff|x-icon|vnd\.microsoft\.icon)|video\/.+|audio\/.+)$/;
|
|
46673
|
+
/**
|
|
46674
|
+
* Content-Disposition to store on an object in a bucket. Public objects can be served straight from the
|
|
46675
|
+
* bucket or a CDN, where Shapio's sandboxing headers are absent; anything that could run as a page there
|
|
46676
|
+
* (SVG, HTML, XML, PDF...) is stored as an attachment, so opening it downloads it. `<img>` tags still show
|
|
46677
|
+
* an SVG, since embedding ignores Content-Disposition.
|
|
46678
|
+
*/
|
|
46679
|
+
const bucketContentDisposition = (contentType) => PASSIVE_INLINE_TYPE.test(contentType.toLowerCase()) ? void 0 : "attachment";
|
|
46680
|
+
//#endregion
|
|
46687
46681
|
//#region src/services/mediaFiles.ts
|
|
46688
46682
|
const notFound = () => new AppError(404, "NOT_FOUND", "Media file not found");
|
|
46689
46683
|
const findFile = async (key) => {
|
|
@@ -47111,6 +47105,16 @@ const insertIfAbsent = async (key, value, trx = db) => {
|
|
|
47111
47105
|
value
|
|
47112
47106
|
}).onConflict((oc) => oc.column("key").doNothing()).returning("key").executeTakeFirst() !== void 0;
|
|
47113
47107
|
};
|
|
47108
|
+
/** Creates or replaces a setting. */
|
|
47109
|
+
const upsertValue = async (key, value, trx = db) => {
|
|
47110
|
+
await trx.insertInto("system_settings").values({
|
|
47111
|
+
key,
|
|
47112
|
+
value
|
|
47113
|
+
}).onConflict((oc) => oc.column("key").doUpdateSet({
|
|
47114
|
+
value,
|
|
47115
|
+
updated_at: /* @__PURE__ */ new Date()
|
|
47116
|
+
})).execute();
|
|
47117
|
+
};
|
|
47114
47118
|
//#endregion
|
|
47115
47119
|
//#region src/services/signingSecret.ts
|
|
47116
47120
|
const SIGNING_SECRET_SETTING = "signing_secret";
|
|
@@ -47616,20 +47620,6 @@ var StartupCheckError = class extends Error {
|
|
|
47616
47620
|
this.name = "StartupCheckError";
|
|
47617
47621
|
}
|
|
47618
47622
|
};
|
|
47619
|
-
/** `host:port/database` (PostgreSQL, MySQL) or the file path (SQLite) from DATABASE_URL, never the credentials. */
|
|
47620
|
-
const describeDatabaseTarget = (connectionString) => {
|
|
47621
|
-
if (dialectOfUrl(connectionString) === "sqlite") {
|
|
47622
|
-
const location = sqliteLocationOfUrl(connectionString);
|
|
47623
|
-
return location.kind === "memory" ? "an in-memory database" : location.path;
|
|
47624
|
-
}
|
|
47625
|
-
try {
|
|
47626
|
-
const url = new URL(connectionString);
|
|
47627
|
-
const defaultPort = dialectOfUrl(connectionString) === "mysql" ? "3306" : "5432";
|
|
47628
|
-
return `${url.hostname}:${url.port || defaultPort}${url.pathname}`;
|
|
47629
|
-
} catch {
|
|
47630
|
-
return "the configured database";
|
|
47631
|
-
}
|
|
47632
|
-
};
|
|
47633
47623
|
const NETWORK_REASONS = {
|
|
47634
47624
|
ECONNREFUSED: "connection refused",
|
|
47635
47625
|
ENOTFOUND: "host not found",
|
|
@@ -49127,6 +49117,45 @@ const createPublishingJobHandlers = (environment) => [
|
|
|
49127
49117
|
];
|
|
49128
49118
|
/** Outbox subscribers: webhook deliveries and deployment triggers follow domain events (ADR 0007). */
|
|
49129
49119
|
const PUBLISHING_OUTBOX_SUBSCRIBERS = [webhookOutboxSubscriber, deploymentOutboxSubscriber];
|
|
49120
|
+
Type.Object({
|
|
49121
|
+
format: Type.Literal(1),
|
|
49122
|
+
publicUrl: Type.String(),
|
|
49123
|
+
basePath: Type.String(),
|
|
49124
|
+
media: Type.Object({
|
|
49125
|
+
publicBaseUrl: Type.Union([Type.String(), Type.Null()]),
|
|
49126
|
+
s3: Type.Union([Type.Object({
|
|
49127
|
+
bucket: Type.String(),
|
|
49128
|
+
region: Type.Union([Type.String(), Type.Null()]),
|
|
49129
|
+
endpoint: Type.Union([Type.String(), Type.Null()]),
|
|
49130
|
+
forcePathStyle: Type.Boolean()
|
|
49131
|
+
}), Type.Null()])
|
|
49132
|
+
})
|
|
49133
|
+
});
|
|
49134
|
+
const toDeliveryDescriptor = ({ server, storage }) => ({
|
|
49135
|
+
format: 1,
|
|
49136
|
+
publicUrl: server.publicUrl,
|
|
49137
|
+
basePath: server.basePath,
|
|
49138
|
+
media: {
|
|
49139
|
+
publicBaseUrl: storage.publicBaseUrl ?? null,
|
|
49140
|
+
s3: storage.s3 ? {
|
|
49141
|
+
bucket: storage.s3.bucket,
|
|
49142
|
+
region: storage.s3.region ?? null,
|
|
49143
|
+
endpoint: storage.s3.endpoint ?? null,
|
|
49144
|
+
forcePathStyle: storage.s3.forcePathStyle
|
|
49145
|
+
} : null
|
|
49146
|
+
}
|
|
49147
|
+
});
|
|
49148
|
+
/**
|
|
49149
|
+
* Called by the server at every start, after migrating: records its release and its delivery descriptor
|
|
49150
|
+
* (rewritten only when it changed), in one transaction.
|
|
49151
|
+
*/
|
|
49152
|
+
const publishServerRelease = async (database, release, source) => {
|
|
49153
|
+
const descriptor = JSON.stringify(toDeliveryDescriptor(source));
|
|
49154
|
+
await database.transaction().execute(async (trx) => {
|
|
49155
|
+
await setRelease(release, trx);
|
|
49156
|
+
if (await findValue("delivery_descriptor", trx) !== descriptor) await upsertValue(DELIVERY_DESCRIPTOR_SETTING, descriptor, trx);
|
|
49157
|
+
});
|
|
49158
|
+
};
|
|
49130
49159
|
//#endregion
|
|
49131
49160
|
//#region src/tls/certificates.ts
|
|
49132
49161
|
/**
|
|
@@ -49287,7 +49316,7 @@ const logStartupSummary = (config, logger) => {
|
|
|
49287
49316
|
};
|
|
49288
49317
|
logger.info(summary, `Shapio ${summary.version} running at ${summary.url} (mode ${summary.mode}, storage ${summary.storage}, worker ${summary.worker}, tls ${summary.tls})`);
|
|
49289
49318
|
};
|
|
49290
|
-
const createConfiguredWorker = (config, db, logger, signingSecret, extensions) => {
|
|
49319
|
+
const createConfiguredWorker = async (config, db, logger, signingSecret, extensions) => {
|
|
49291
49320
|
const publishing = createPublishingJobEnvironment(createPublishingRuntime({
|
|
49292
49321
|
db,
|
|
49293
49322
|
signingSecret,
|
|
@@ -49300,7 +49329,7 @@ const createConfiguredWorker = (config, db, logger, signingSecret, extensions) =
|
|
|
49300
49329
|
urls: createUrlBuilder(config.server),
|
|
49301
49330
|
transport: createEmailTransport(config.email, logger.child({ component: "email" }))
|
|
49302
49331
|
};
|
|
49303
|
-
const storage = createMediaStorage(config.storage, { urls: createUrlBuilder(config.server) });
|
|
49332
|
+
const storage = await createMediaStorage(config.storage, { urls: createUrlBuilder(config.server) });
|
|
49304
49333
|
return createWorker({
|
|
49305
49334
|
db,
|
|
49306
49335
|
handlers: createJobHandlers([
|
|
@@ -49381,6 +49410,7 @@ const startServer = async (config) => {
|
|
|
49381
49410
|
log: logger
|
|
49382
49411
|
});
|
|
49383
49412
|
const signingSecret = await resolveSigningSecret(db, config.sessionSecret, logger);
|
|
49413
|
+
await publishServerRelease(db, SHAPIO_VERSION, config);
|
|
49384
49414
|
extensions = await startExtensions(config, db, logger, project);
|
|
49385
49415
|
const app = await buildApp(config, {
|
|
49386
49416
|
db,
|
|
@@ -49390,7 +49420,7 @@ const startServer = async (config) => {
|
|
|
49390
49420
|
schemaListen: config.schema.listen,
|
|
49391
49421
|
...tls.initial ? { tls: tls.initial } : {}
|
|
49392
49422
|
});
|
|
49393
|
-
const worker = config.worker.mode === "inline" ? createConfiguredWorker(config, db, logger, signingSecret, extensions) : void 0;
|
|
49423
|
+
const worker = config.worker.mode === "inline" ? await createConfiguredWorker(config, db, logger, signingSecret, extensions) : void 0;
|
|
49394
49424
|
const tlsRuntime = tls;
|
|
49395
49425
|
const extensionRuntime = extensions;
|
|
49396
49426
|
let closing;
|
|
@@ -49464,7 +49494,7 @@ const startDedicatedWorker = async (config) => {
|
|
|
49464
49494
|
}
|
|
49465
49495
|
const signingSecret = await resolveSigningSecret(db, config.sessionSecret, logger);
|
|
49466
49496
|
const extensions = await startExtensions(config, db, logger, project);
|
|
49467
|
-
const worker = createConfiguredWorker(config, db, logger, signingSecret, extensions);
|
|
49497
|
+
const worker = await createConfiguredWorker(config, db, logger, signingSecret, extensions);
|
|
49468
49498
|
await ensureRetentionScheduled(db);
|
|
49469
49499
|
await ensureHealthSweepScheduled(db);
|
|
49470
49500
|
worker.start();
|
|
@@ -49478,6 +49508,6 @@ const startDedicatedWorker = async (config) => {
|
|
|
49478
49508
|
return worker;
|
|
49479
49509
|
};
|
|
49480
49510
|
//#endregion
|
|
49481
|
-
export {
|
|
49511
|
+
export { parseLockFile as $, buildEditorManifest as A, RESERVED_DEFINITION_API_KEYS as B, loopbackUrl as C, BEFORE_EVENTS as D, AFTER_EVENTS as E, lockById$5 as F, THEME_VARIANTS as G, RESERVED_TYPE_NAMES as H, update$8 as I, hashDefinition as J, checkThemeContrast as K, STORAGE_DRIVERS$1 as L, isValidStorageKey as M, listForAssets as N, EXTENSION_JOB_PREFIX as O, listLiveByDriver as P, parseDefinition as Q, describeError as R, createUrlBuilder as S, loadProjectConfig as T, SCHEMA_KIND_DIRECTORIES as U, RESERVED_FIELD_API_KEYS as V, SITES_DIRECTORY as W, lockEntriesForSite as X, lockCoversSite as Y, mergePulledLock as Z, listAllSites as _, loadConfig as a, toTypeName as at, generateToken as b, bucketContentDisposition as c, withSiteCovered as ct, migrateToLatest as d, createStableId as dt, schemaFilePath as et, SHAPIO_VERSION as f, validateRichText as ft, createSite$1 as g, ObjectNotFoundError as h, assertDatabaseReachable as i, suggestPlural as it, encodeKeyPath as j, EXTENSION_ROUTE_ROOT as k, contentDisposition as l, RICHTEXT_FORMAT as lt, InvalidStorageKeyError as m, sqliteDriverOf as mt, startServer as n, serializeDefinition as nt, loadEnvFileIfPresent as o, upgradeLockFile as ot, createMediaStorage as p, createDb as pt, foldApiKey as q, copyObjectVerified as r, serializeLockFile as rt, buildApp as s, validateSchema as st, startDedicatedWorker as t, scopeDirectory as tt, getPendingMigrations as u, SAFE_LINK_PATTERN as ut, createAdminDirect as v, SITE_KEY_PATTERN as w, createLogger as x, SYSTEM_CLI_ACTOR as y, LOCK_FILE_PATH as z };
|
|
49482
49512
|
|
|
49483
|
-
//# sourceMappingURL=worker-
|
|
49513
|
+
//# sourceMappingURL=worker-jz_0yAmS.js.map
|