headroom-cms 0.1.3 → 0.1.5

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.
Files changed (119) hide show
  1. package/admin/assets/AdminsPage-C4tJy6Vj.js +1 -0
  2. package/admin/assets/AllContentPage-DL0-UlYh.js +1 -0
  3. package/admin/assets/ApiKeysPage-pZ6nKCZ_.js +1 -0
  4. package/admin/assets/AuditPage-aVmcP6Ts.js +1 -0
  5. package/admin/assets/{BlockEditor-C0KaZUHQ.js → BlockEditor-D0Jk8u7w.js} +54 -54
  6. package/admin/assets/BlockTypeEditPage-DIe2yYEr.js +1 -0
  7. package/admin/assets/BlockTypesPage-Q7keQKxn.js +1 -0
  8. package/admin/assets/BulkActionBar-BGDrNwCg.js +1 -0
  9. package/admin/assets/CollectionEditPage-Bq75MpXk.js +1 -0
  10. package/admin/assets/CollectionsPage-DDZ-5H7Y.js +1 -0
  11. package/admin/assets/ContentCreatePage-C3jn0Etf.js +1 -0
  12. package/admin/assets/ContentEditPage-9tODvFEv.js +2 -0
  13. package/admin/assets/ContentListPage-VCT6GTCF.js +1 -0
  14. package/admin/assets/{CustomBlockPreview-CCiZrZhi.js → CustomBlockPreview-f9j4g35U.js} +1 -1
  15. package/admin/assets/FieldBuilder-p1Y8RubR.js +3 -0
  16. package/admin/assets/{LoginPage-BlJXP0GH.js → LoginPage-9YUPS1YH.js} +1 -1
  17. package/admin/assets/MediaField-DJpYbUA8.js +1 -0
  18. package/admin/assets/MediaPage-BgDRQR21.js +1 -0
  19. package/admin/assets/SiteSettingsPage-Diy-PauR.js +1 -0
  20. package/admin/assets/SiteUsersPage-CtVaB0vq.js +1 -0
  21. package/admin/assets/SitesPage-B-sNyP-Y.js +1 -0
  22. package/admin/assets/SubmissionDetailPage-DW6QJvAy.js +1 -0
  23. package/admin/assets/SubmissionEditPage-CxYPdI9-.js +1 -0
  24. package/admin/assets/SubmissionListPage-BHF82NF3.js +1 -0
  25. package/admin/assets/TagInput-CrI2BIuz.js +1 -0
  26. package/admin/assets/TagsPage-BSX5KQvZ.js +1 -0
  27. package/admin/assets/UsersPage-BCTpWULa.js +1 -0
  28. package/admin/assets/WebhookEditPage-CQO3nmaT.js +1 -0
  29. package/admin/assets/WebhooksPage-ByaTlUGU.js +1 -0
  30. package/admin/assets/{card-DpNr7WTb.js → card-uKxSQehY.js} +1 -1
  31. package/admin/assets/checkbox-z1kYnX5o.js +1 -0
  32. package/admin/assets/command-CuWC4GrT.js +1 -0
  33. package/admin/assets/{core.esm-BtFZvlg0.js → core.esm-B_kcYf6n.js} +2 -2
  34. package/admin/assets/index-HoCNSqv2.css +1 -0
  35. package/admin/assets/index-b-u0-VCO.js +18 -0
  36. package/admin/assets/media-url-DIg_vSyf.js +1 -0
  37. package/admin/assets/popover-rcnajqN6.js +1 -0
  38. package/admin/assets/{radix-n1vDIPi6.js → radix-C1kb_NqW.js} +2 -2
  39. package/admin/assets/react-vendor-C2CvUxFh.js +4 -0
  40. package/admin/assets/select-BKaV0BO_.js +1 -0
  41. package/admin/assets/serializeToText-BfR2RCzd.js +2 -0
  42. package/admin/assets/sortable.esm-BHilUL-2.js +1 -0
  43. package/admin/assets/{table-D4rLgOKa.js → table-Bozosvl6.js} +1 -1
  44. package/admin/assets/{tanstack-BO6c-AOu.js → tanstack-Bs3zYPPV.js} +1 -1
  45. package/admin/assets/textarea-BnjAxJtk.js +1 -0
  46. package/admin/assets/useAdminResolver-B0ady82Q.js +1 -0
  47. package/admin/assets/useContent-B2MUK4An.js +1 -0
  48. package/admin/assets/{useDebouncedValue-Bf8UizjU.js → useDebouncedValue-C-cQUcLG.js} +1 -1
  49. package/admin/assets/useMedia-CXQpRNYL.js +1 -0
  50. package/admin/assets/usePageTitle-Do4xyFdL.js +1 -0
  51. package/admin/assets/useSiteUsers-BfzIdhvs.js +1 -0
  52. package/admin/assets/{useTags-BB47vbXO.js → useTags-B6FtXCHF.js} +1 -1
  53. package/admin/assets/{useWebhooks-DS4Ee8Wk.js → useWebhooks-iPRX5y4s.js} +1 -1
  54. package/admin/favicon-16x16.png +0 -0
  55. package/admin/favicon-32x32.png +0 -0
  56. package/admin/index.html +7 -6
  57. package/admin/sw.js +1 -1
  58. package/dist/api.d.ts.map +1 -1
  59. package/dist/api.js +8 -0
  60. package/dist/api.js.map +1 -1
  61. package/dist/index.d.ts +3 -0
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.js +12 -2
  64. package/dist/index.js.map +1 -1
  65. package/dist/scheduler.d.ts +25 -0
  66. package/dist/scheduler.d.ts.map +1 -0
  67. package/dist/scheduler.js +64 -0
  68. package/dist/scheduler.js.map +1 -0
  69. package/dist/storage.d.ts +1 -0
  70. package/dist/storage.d.ts.map +1 -1
  71. package/dist/storage.js +16 -0
  72. package/dist/storage.js.map +1 -1
  73. package/lambda/api/bootstrap +0 -0
  74. package/lambda/webhook-worker/bootstrap +0 -0
  75. package/package.json +1 -1
  76. package/src/api.ts +8 -0
  77. package/src/index.ts +16 -2
  78. package/src/scheduler.ts +83 -0
  79. package/src/sst-env.d.ts +4 -0
  80. package/src/storage.ts +17 -0
  81. package/admin/assets/AdminsPage-DYJhlQnA.js +0 -1
  82. package/admin/assets/AllContentPage-DShBvFru.js +0 -1
  83. package/admin/assets/ApiKeysPage-DONrd-TJ.js +0 -1
  84. package/admin/assets/AuditPage-BwhYu96L.js +0 -1
  85. package/admin/assets/BlockTypeEditPage-BYJfEA6l.js +0 -1
  86. package/admin/assets/BlockTypesPage-Pf9u78-O.js +0 -1
  87. package/admin/assets/BulkActionBar-BX-t8fyM.js +0 -1
  88. package/admin/assets/CollectionEditPage-CQGo9Cbu.js +0 -1
  89. package/admin/assets/CollectionsPage-D-QTkoW_.js +0 -1
  90. package/admin/assets/ContentCreatePage-DujNZXXj.js +0 -1
  91. package/admin/assets/ContentEditPage-DyqgEoAe.js +0 -3
  92. package/admin/assets/ContentListPage-llAlhZTH.js +0 -1
  93. package/admin/assets/FieldBuilder-B3-3MTqp.js +0 -3
  94. package/admin/assets/MediaPage-Cad4n33B.js +0 -1
  95. package/admin/assets/SiteSettingsPage-xfAm3ZKQ.js +0 -1
  96. package/admin/assets/SitesPage-DnCiSu23.js +0 -1
  97. package/admin/assets/TagsPage-DNlaoFCE.js +0 -1
  98. package/admin/assets/UsersPage-D_nOx6W9.js +0 -1
  99. package/admin/assets/WebhookEditPage-BUvLl4rY.js +0 -1
  100. package/admin/assets/WebhooksPage-CG7WC9Bq.js +0 -1
  101. package/admin/assets/badge-ChZ2DZue.js +0 -1
  102. package/admin/assets/check-BMpruHpO.js +0 -1
  103. package/admin/assets/checkbox-VtCfoGic.js +0 -1
  104. package/admin/assets/command-98iA8Va4.js +0 -1
  105. package/admin/assets/copy-fXL6Ngxi.js +0 -1
  106. package/admin/assets/index-CwkwXbO-.js +0 -18
  107. package/admin/assets/index-FYfbavkE.css +0 -1
  108. package/admin/assets/plus-2Ds_MoqB.js +0 -1
  109. package/admin/assets/popover-DFInMOpa.js +0 -1
  110. package/admin/assets/react-vendor-DNVhVxD7.js +0 -4
  111. package/admin/assets/search-DRNC6QB5.js +0 -1
  112. package/admin/assets/select-Cj54Wt-H.js +0 -1
  113. package/admin/assets/sortable.esm-BUhmZW2_.js +0 -1
  114. package/admin/assets/trash-2-CbbWF_O4.js +0 -1
  115. package/admin/assets/use-mobile-Cvl5tIVY.js +0 -1
  116. package/admin/assets/useAdminResolver-B-_1f6SR.js +0 -1
  117. package/admin/assets/useContent-Cp41wBYR.js +0 -1
  118. package/admin/assets/useMedia-DjiNKMOU.js +0 -1
  119. package/admin/vite.svg +0 -1
package/admin/index.html CHANGED
@@ -2,7 +2,8 @@
2
2
  <html lang="en">
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
- <link rel="icon" type="image/svg+xml" href="/vite.svg" />
5
+ <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
6
+ <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
6
7
  <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
7
8
  <meta name="theme-color" content="#0a0a0a" />
8
9
  <meta name="apple-mobile-web-app-capable" content="yes" />
@@ -10,11 +11,11 @@
10
11
  <meta name="apple-mobile-web-app-title" content="Headroom" />
11
12
  <link rel="apple-touch-icon" href="/icons/icon-180x180.png" />
12
13
  <title>Headroom CMS</title>
13
- <script type="module" crossorigin src="/assets/index-CwkwXbO-.js"></script>
14
- <link rel="modulepreload" crossorigin href="/assets/react-vendor-DNVhVxD7.js">
15
- <link rel="modulepreload" crossorigin href="/assets/tanstack-BO6c-AOu.js">
16
- <link rel="modulepreload" crossorigin href="/assets/radix-n1vDIPi6.js">
17
- <link rel="stylesheet" crossorigin href="/assets/index-FYfbavkE.css">
14
+ <script type="module" crossorigin src="/assets/index-b-u0-VCO.js"></script>
15
+ <link rel="modulepreload" crossorigin href="/assets/react-vendor-C2CvUxFh.js">
16
+ <link rel="modulepreload" crossorigin href="/assets/tanstack-Bs3zYPPV.js">
17
+ <link rel="modulepreload" crossorigin href="/assets/radix-C1kb_NqW.js">
18
+ <link rel="stylesheet" crossorigin href="/assets/index-HoCNSqv2.css">
18
19
  <link rel="manifest" href="/manifest.webmanifest"></head>
19
20
  <body>
20
21
  <script>
package/admin/sw.js CHANGED
@@ -1 +1 @@
1
- if(!self.define){let s,e={};const l=(l,i)=>(l=new URL(l+".js",i).href,e[l]||new Promise(e=>{if("document"in self){const s=document.createElement("script");s.src=l,s.onload=e,document.head.appendChild(s)}else s=l,importScripts(l),e()}).then(()=>{let s=e[l];if(!s)throw new Error(`Module ${l} didn’t register its module`);return s}));self.define=(i,n)=>{const r=s||("document"in self?document.currentScript.src:"")||location.href;if(e[r])return;let u={};const o=s=>l(s,r),a={module:{uri:r},exports:u,require:o};e[r]=Promise.all(i.map(s=>a[s]||o(s))).then(s=>(n(...s),u))}}define(["./workbox-7d58179f"],function(s){"use strict";self.skipWaiting(),s.clientsClaim(),s.precacheAndRoute([{url:"vite.svg",revision:"8e3a10e157f75ada21ab742c022d5430"},{url:"index.html",revision:"c26a1e99ad36b20ccc332e80223d3e6c"},{url:"icons/maskable-icon-512x512.png",revision:"d6913dcae3805185fad0790a20eae097"},{url:"icons/icon-512x512.png",revision:"ed25f5ccf87506782ee42be66318531b"},{url:"icons/icon-192x192.png",revision:"578d0c18e97882eaae9436f3bdd3c446"},{url:"icons/icon-180x180.png",revision:"8a45d7715a9f2f3a8b929a791b4a67e1"},{url:"assets/workbox-window.prod.es5-BIl4cyR9.js",revision:null},{url:"assets/useWebhooks-DS4Ee8Wk.js",revision:null},{url:"assets/useTags-BB47vbXO.js",revision:null},{url:"assets/useMedia-DjiNKMOU.js",revision:null},{url:"assets/useDebouncedValue-Bf8UizjU.js",revision:null},{url:"assets/useContent-Cp41wBYR.js",revision:null},{url:"assets/useAdminResolver-B-_1f6SR.js",revision:null},{url:"assets/use-mobile-Cvl5tIVY.js",revision:null},{url:"assets/trash-2-CbbWF_O4.js",revision:null},{url:"assets/tanstack-BO6c-AOu.js",revision:null},{url:"assets/table-D4rLgOKa.js",revision:null},{url:"assets/sortable.esm-BUhmZW2_.js",revision:null},{url:"assets/select-Cj54Wt-H.js",revision:null},{url:"assets/search-DRNC6QB5.js",revision:null},{url:"assets/react-vendor-DNVhVxD7.js",revision:null},{url:"assets/radix-n1vDIPi6.js",revision:null},{url:"assets/popover-DFInMOpa.js",revision:null},{url:"assets/plus-2Ds_MoqB.js",revision:null},{url:"assets/native-48B9X9Wg.js",revision:null},{url:"assets/module-RjUF93sV.js",revision:null},{url:"assets/lib-BrI1UB_t.js",revision:null},{url:"assets/index-FYfbavkE.css",revision:null},{url:"assets/index-CwkwXbO-.js",revision:null},{url:"assets/format-C88SDH8g.js",revision:null},{url:"assets/core.esm-BtFZvlg0.js",revision:null},{url:"assets/copy-fXL6Ngxi.js",revision:null},{url:"assets/contentStatus-BmaiYVOm.js",revision:null},{url:"assets/command-98iA8Va4.js",revision:null},{url:"assets/checkbox-VtCfoGic.js",revision:null},{url:"assets/check-BMpruHpO.js",revision:null},{url:"assets/card-DpNr7WTb.js",revision:null},{url:"assets/badge-ChZ2DZue.js",revision:null},{url:"assets/WebhooksPage-CG7WC9Bq.js",revision:null},{url:"assets/WebhookEditPage-BUvLl4rY.js",revision:null},{url:"assets/UsersPage-D_nOx6W9.js",revision:null},{url:"assets/TagsPage-DNlaoFCE.js",revision:null},{url:"assets/SitesPage-DnCiSu23.js",revision:null},{url:"assets/SiteSettingsPage-xfAm3ZKQ.js",revision:null},{url:"assets/MediaPage-DfPQBmNf.css",revision:null},{url:"assets/MediaPage-Cad4n33B.js",revision:null},{url:"assets/LoginPage-BlJXP0GH.js",revision:null},{url:"assets/FieldBuilder-B3-3MTqp.js",revision:null},{url:"assets/CustomBlockPreview-CCiZrZhi.js",revision:null},{url:"assets/ContentListPage-llAlhZTH.js",revision:null},{url:"assets/ContentEditPage-DyqgEoAe.js",revision:null},{url:"assets/ContentCreatePage-DujNZXXj.js",revision:null},{url:"assets/CollectionsPage-D-QTkoW_.js",revision:null},{url:"assets/CollectionEditPage-CQGo9Cbu.js",revision:null},{url:"assets/BulkActionBar-BX-t8fyM.js",revision:null},{url:"assets/BlockTypesPage-Pf9u78-O.js",revision:null},{url:"assets/BlockTypeEditPage-BYJfEA6l.js",revision:null},{url:"assets/BlockEditor-Cp_wZ2xN.css",revision:null},{url:"assets/BlockEditor-C0KaZUHQ.js",revision:null},{url:"assets/AuditPage-BwhYu96L.js",revision:null},{url:"assets/ApiKeysPage-DONrd-TJ.js",revision:null},{url:"assets/AllContentPage-DShBvFru.js",revision:null},{url:"assets/AdminsPage-DYJhlQnA.js",revision:null},{url:"icons/icon-180x180.png",revision:"8a45d7715a9f2f3a8b929a791b4a67e1"},{url:"icons/icon-192x192.png",revision:"578d0c18e97882eaae9436f3bdd3c446"},{url:"icons/icon-512x512.png",revision:"ed25f5ccf87506782ee42be66318531b"},{url:"icons/maskable-icon-512x512.png",revision:"d6913dcae3805185fad0790a20eae097"},{url:"manifest.webmanifest",revision:"be12a951409033222ff660a548620488"}],{}),s.cleanupOutdatedCaches(),s.registerRoute(new s.NavigationRoute(s.createHandlerBoundToURL("index.html"),{denylist:[/^\/v1\//]})),s.registerRoute(({url:s})=>s.pathname.startsWith("/v1/admin/"),new s.NetworkFirst({cacheName:"api-cache",networkTimeoutSeconds:10,plugins:[new s.ExpirationPlugin({maxEntries:200,maxAgeSeconds:3600}),new s.CacheableResponsePlugin({statuses:[200]})]}),"GET"),s.registerRoute(({request:s})=>"image"===s.destination,new s.CacheFirst({cacheName:"media-cache",plugins:[new s.ExpirationPlugin({maxEntries:500,maxAgeSeconds:604800}),new s.CacheableResponsePlugin({statuses:[200]})]}),"GET")});
1
+ if(!self.define){let s,e={};const i=(i,l)=>(i=new URL(i+".js",l).href,e[i]||new Promise(e=>{if("document"in self){const s=document.createElement("script");s.src=i,s.onload=e,document.head.appendChild(s)}else s=i,importScripts(i),e()}).then(()=>{let s=e[i];if(!s)throw new Error(`Module ${i} didn’t register its module`);return s}));self.define=(l,n)=>{const r=s||("document"in self?document.currentScript.src:"")||location.href;if(e[r])return;let u={};const a=s=>i(s,r),o={module:{uri:r},exports:u,require:a};e[r]=Promise.all(l.map(s=>o[s]||a(s))).then(s=>(n(...s),u))}}define(["./workbox-7d58179f"],function(s){"use strict";self.skipWaiting(),s.clientsClaim(),s.precacheAndRoute([{url:"index.html",revision:"59ada9c0834c803c5f4933f437b702d9"},{url:"favicon-32x32.png",revision:"b3444a97a94af8708e3af842395316b9"},{url:"favicon-16x16.png",revision:"6ac0bbd011d9edf37858e0459d580887"},{url:"icons/maskable-icon-512x512.png",revision:"d6913dcae3805185fad0790a20eae097"},{url:"icons/icon-512x512.png",revision:"ed25f5ccf87506782ee42be66318531b"},{url:"icons/icon-192x192.png",revision:"578d0c18e97882eaae9436f3bdd3c446"},{url:"icons/icon-180x180.png",revision:"8a45d7715a9f2f3a8b929a791b4a67e1"},{url:"assets/workbox-window.prod.es5-BIl4cyR9.js",revision:null},{url:"assets/useWebhooks-iPRX5y4s.js",revision:null},{url:"assets/useTags-B6FtXCHF.js",revision:null},{url:"assets/useSiteUsers-BfzIdhvs.js",revision:null},{url:"assets/usePageTitle-Do4xyFdL.js",revision:null},{url:"assets/useMedia-CXQpRNYL.js",revision:null},{url:"assets/useDebouncedValue-C-cQUcLG.js",revision:null},{url:"assets/useContent-B2MUK4An.js",revision:null},{url:"assets/useAdminResolver-B0ady82Q.js",revision:null},{url:"assets/textarea-BnjAxJtk.js",revision:null},{url:"assets/tanstack-Bs3zYPPV.js",revision:null},{url:"assets/table-Bozosvl6.js",revision:null},{url:"assets/sortable.esm-BHilUL-2.js",revision:null},{url:"assets/serializeToText-BfR2RCzd.js",revision:null},{url:"assets/select-BKaV0BO_.js",revision:null},{url:"assets/react-vendor-C2CvUxFh.js",revision:null},{url:"assets/radix-C1kb_NqW.js",revision:null},{url:"assets/popover-rcnajqN6.js",revision:null},{url:"assets/native-48B9X9Wg.js",revision:null},{url:"assets/module-RjUF93sV.js",revision:null},{url:"assets/media-url-DIg_vSyf.js",revision:null},{url:"assets/lib-BrI1UB_t.js",revision:null},{url:"assets/index-b-u0-VCO.js",revision:null},{url:"assets/index-HoCNSqv2.css",revision:null},{url:"assets/format-C88SDH8g.js",revision:null},{url:"assets/core.esm-B_kcYf6n.js",revision:null},{url:"assets/contentStatus-BmaiYVOm.js",revision:null},{url:"assets/command-CuWC4GrT.js",revision:null},{url:"assets/checkbox-z1kYnX5o.js",revision:null},{url:"assets/card-uKxSQehY.js",revision:null},{url:"assets/WebhooksPage-ByaTlUGU.js",revision:null},{url:"assets/WebhookEditPage-CQO3nmaT.js",revision:null},{url:"assets/UsersPage-BCTpWULa.js",revision:null},{url:"assets/TagsPage-BSX5KQvZ.js",revision:null},{url:"assets/TagInput-CrI2BIuz.js",revision:null},{url:"assets/SubmissionListPage-BHF82NF3.js",revision:null},{url:"assets/SubmissionEditPage-CxYPdI9-.js",revision:null},{url:"assets/SubmissionDetailPage-DW6QJvAy.js",revision:null},{url:"assets/SitesPage-B-sNyP-Y.js",revision:null},{url:"assets/SiteUsersPage-CtVaB0vq.js",revision:null},{url:"assets/SiteSettingsPage-Diy-PauR.js",revision:null},{url:"assets/MediaPage-DfPQBmNf.css",revision:null},{url:"assets/MediaPage-BgDRQR21.js",revision:null},{url:"assets/MediaField-DJpYbUA8.js",revision:null},{url:"assets/LoginPage-9YUPS1YH.js",revision:null},{url:"assets/FieldBuilder-p1Y8RubR.js",revision:null},{url:"assets/CustomBlockPreview-f9j4g35U.js",revision:null},{url:"assets/ContentListPage-VCT6GTCF.js",revision:null},{url:"assets/ContentEditPage-9tODvFEv.js",revision:null},{url:"assets/ContentCreatePage-C3jn0Etf.js",revision:null},{url:"assets/CollectionsPage-DDZ-5H7Y.js",revision:null},{url:"assets/CollectionEditPage-Bq75MpXk.js",revision:null},{url:"assets/BulkActionBar-BGDrNwCg.js",revision:null},{url:"assets/BlockTypesPage-Q7keQKxn.js",revision:null},{url:"assets/BlockTypeEditPage-DIe2yYEr.js",revision:null},{url:"assets/BlockEditor-D0Jk8u7w.js",revision:null},{url:"assets/BlockEditor-Cp_wZ2xN.css",revision:null},{url:"assets/AuditPage-aVmcP6Ts.js",revision:null},{url:"assets/ApiKeysPage-pZ6nKCZ_.js",revision:null},{url:"assets/AllContentPage-DL0-UlYh.js",revision:null},{url:"assets/AdminsPage-C4tJy6Vj.js",revision:null},{url:"icons/icon-180x180.png",revision:"8a45d7715a9f2f3a8b929a791b4a67e1"},{url:"icons/icon-192x192.png",revision:"578d0c18e97882eaae9436f3bdd3c446"},{url:"icons/icon-512x512.png",revision:"ed25f5ccf87506782ee42be66318531b"},{url:"icons/maskable-icon-512x512.png",revision:"d6913dcae3805185fad0790a20eae097"},{url:"manifest.webmanifest",revision:"be12a951409033222ff660a548620488"}],{}),s.cleanupOutdatedCaches(),s.registerRoute(new s.NavigationRoute(s.createHandlerBoundToURL("index.html"),{denylist:[/^\/v1\//]})),s.registerRoute(({url:s})=>s.pathname.startsWith("/v1/admin/"),new s.NetworkFirst({cacheName:"api-cache",networkTimeoutSeconds:10,plugins:[new s.ExpirationPlugin({maxEntries:200,maxAgeSeconds:3600}),new s.CacheableResponsePlugin({statuses:[200]})]}),"GET"),s.registerRoute(({request:s})=>"image"===s.destination,new s.CacheFirst({cacheName:"media-cache",plugins:[new s.ExpirationPlugin({maxEntries:500,maxAgeSeconds:604800}),new s.CacheableResponsePlugin({statuses:[200]})]}),"GET")});
package/dist/api.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,IAAI,EAAE,aAAa,CAAC;IACpB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,KAAK,EAAE,cAAc,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE;QACJ,0CAA0C;QAC1C,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO;;EAqFpD;AAED,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,IAAI,EAAE,aAAa,CAAC;IACpB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,KAAK,EAAE,cAAc,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE;QACJ,0CAA0C;QAC1C,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO;;EA6FpD;AAED,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC"}
package/dist/api.js CHANGED
@@ -44,6 +44,8 @@ export function createApi(name, args) {
44
44
  IMAGE_SIGNING_SECRET: image.imageSigningSecret.value,
45
45
  IMAGE_LAMBDA_NAME: image.imageLambda.name,
46
46
  RELATIONSHIPS_TABLE: storage.relationships.name,
47
+ SITE_USERS_TABLE: storage.siteUsers.name,
48
+ SES_FROM_EMAIL: "noreply@headroom.dev",
47
49
  },
48
50
  link: [
49
51
  storage.sites,
@@ -60,6 +62,7 @@ export function createApi(name, args) {
60
62
  webhooks.webhookDeliveryQueue,
61
63
  image.imageSigningSecret,
62
64
  storage.relationships,
65
+ storage.siteUsers,
63
66
  ],
64
67
  permissions: [
65
68
  {
@@ -77,6 +80,7 @@ export function createApi(name, args) {
77
80
  "cognito-idp:AdminCreateUser",
78
81
  "cognito-idp:AdminDeleteUser",
79
82
  "cognito-idp:AdminGetUser",
83
+ "cognito-idp:AdminInitiateAuth",
80
84
  ],
81
85
  resources: [auth.userPool.arn],
82
86
  },
@@ -84,6 +88,10 @@ export function createApi(name, args) {
84
88
  actions: ["lambda:InvokeFunction"],
85
89
  resources: [image.imageLambda.arn],
86
90
  },
91
+ {
92
+ actions: ["ses:SendEmail", "ses:SendRawEmail"],
93
+ resources: ["*"],
94
+ },
87
95
  ],
88
96
  });
89
97
  return { api };
package/dist/api.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -10,6 +10,7 @@ export type { WebhookResources } from "./webhooks.js";
10
10
  export type { ImageResources } from "./image.js";
11
11
  export type { ApiResources } from "./api.js";
12
12
  export type { CdnResources } from "./cdn.js";
13
+ export type { SchedulerResources } from "./scheduler.js";
13
14
  export type { AdminSiteResources } from "./admin-site.js";
14
15
  export interface HeadroomCMSArgs {
15
16
  /**
@@ -71,6 +72,8 @@ export interface HeadroomCMSArgs {
71
72
  imageLambdaHandler: string;
72
73
  /** Path to admin UI source, e.g. "packages/admin" */
73
74
  adminPath: string;
75
+ /** Go source path for scheduler Lambda, e.g. "packages/scheduler" */
76
+ schedulerHandler?: string;
74
77
  };
75
78
  }
76
79
  export declare class HeadroomCMS {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAuCH,YAAY,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC/C,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAE1D,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,MAAM,CAAC,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,gEAAgE;QAChE,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;IAEF;;;OAGG;IACH,WAAW,CAAC,EAAE;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,gEAAgE;QAChE,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;IAEF;;;OAGG;IACH,UAAU,CAAC,EAAE,gBAAgB,GAAG,gBAAgB,GAAG,gBAAgB,CAAC;IAEpE;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,cAAc,CAAC,EAAE;QACf,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAC3B,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,cAAc,CAAC,EAAE,OAAO,CAAC;KAC1B,CAAC;IAEF;;;OAGG;IACH,GAAG,CAAC,EAAE;QACJ,yDAAyD;QACzD,UAAU,EAAE,MAAM,CAAC;QACnB,wEAAwE;QACxE,oBAAoB,EAAE,MAAM,CAAC;QAC7B,gGAAgG;QAChG,oBAAoB,EAAE,MAAM,CAAC;QAC7B,+EAA+E;QAC/E,kBAAkB,EAAE,MAAM,CAAC;QAC3B,qDAAqD;QACrD,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,qBAAa,WAAW;IACtB,SAAgB,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC7C,SAAgB,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC7C,SAAgB,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC/C,SAAgB,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACjD,SAAgB,gBAAgB,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAEvD,SAAgB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;gBAElD,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe;CAqFhD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAwCH,YAAY,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC/C,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,YAAY,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAE1D,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,MAAM,CAAC,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,gEAAgE;QAChE,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;IAEF;;;OAGG;IACH,WAAW,CAAC,EAAE;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,gEAAgE;QAChE,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;IAEF;;;OAGG;IACH,UAAU,CAAC,EAAE,gBAAgB,GAAG,gBAAgB,GAAG,gBAAgB,CAAC;IAEpE;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,cAAc,CAAC,EAAE;QACf,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAC3B,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,cAAc,CAAC,EAAE,OAAO,CAAC;KAC1B,CAAC;IAEF;;;OAGG;IACH,GAAG,CAAC,EAAE;QACJ,yDAAyD;QACzD,UAAU,EAAE,MAAM,CAAC;QACnB,wEAAwE;QACxE,oBAAoB,EAAE,MAAM,CAAC;QAC7B,gGAAgG;QAChG,oBAAoB,EAAE,MAAM,CAAC;QAC7B,+EAA+E;QAC/E,kBAAkB,EAAE,MAAM,CAAC;QAC3B,qDAAqD;QACrD,SAAS,EAAE,MAAM,CAAC;QAClB,qEAAqE;QACrE,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B,CAAC;CACH;AAED,qBAAa,WAAW;IACtB,SAAgB,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC7C,SAAgB,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC7C,SAAgB,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC/C,SAAgB,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACjD,SAAgB,gBAAgB,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAEvD,SAAgB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;gBAElD,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe;CA+FhD"}
package/dist/index.js CHANGED
@@ -12,6 +12,7 @@ import { createWebhooks } from "./webhooks.js";
12
12
  import { createImage } from "./image.js";
13
13
  import { createApi } from "./api.js";
14
14
  import { createCdn } from "./cdn.js";
15
+ import { createScheduler } from "./scheduler.js";
15
16
  import { createAdminSite } from "./admin-site.js";
16
17
  /**
17
18
  * Resolve the headroom-cms package root directory.
@@ -85,7 +86,16 @@ export class HeadroomCMS {
85
86
  ? { handler: args.dev.apiHandler }
86
87
  : undefined,
87
88
  });
88
- // 6. CDN (CloudFront distribution + edge functions)
89
+ // 6. Scheduler (EventBridge cron + Go Lambda + lock table)
90
+ const schedulerResources = createScheduler(name, {
91
+ storage,
92
+ api,
93
+ pkgRoot,
94
+ dev: args.dev?.schedulerHandler
95
+ ? { handler: args.dev.schedulerHandler }
96
+ : undefined,
97
+ });
98
+ // 7. CDN (CloudFront distribution + edge functions)
89
99
  const cdn = createCdn(name, {
90
100
  api,
91
101
  image,
@@ -95,7 +105,7 @@ export class HeadroomCMS {
95
105
  apiCacheTtl: args.apiCacheTtl,
96
106
  domain: args.domain,
97
107
  });
98
- // 7. Admin UI (static site)
108
+ // 8. Admin UI (static site)
99
109
  const admin = createAdminSite(name, {
100
110
  api,
101
111
  cdn,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Scheduler Infrastructure
3
+ *
4
+ * Defines the scheduler Lambda for auto-publishing scheduled content:
5
+ * - EventBridge rule (every 5 minutes)
6
+ * - Scheduler Lambda (Go)
7
+ * - DynamoDB lock table
8
+ */
9
+ import type { StorageResources } from "./storage.js";
10
+ import type { ApiResources } from "./api.js";
11
+ export interface SchedulerArgs {
12
+ storage: StorageResources;
13
+ api: ApiResources;
14
+ pkgRoot: string;
15
+ dev?: {
16
+ /** Go source path, e.g. "packages/scheduler" */
17
+ handler: string;
18
+ };
19
+ }
20
+ export declare function createScheduler(name: string, args: SchedulerArgs): {
21
+ schedulerLock: sst.aws.Dynamo;
22
+ schedulerCron: sst.aws.Cron;
23
+ };
24
+ export type SchedulerResources = ReturnType<typeof createScheduler>;
25
+ //# sourceMappingURL=scheduler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,gBAAgB,CAAC;IAC1B,GAAG,EAAE,YAAY,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE;QACJ,gDAAgD;QAChD,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa;;;EAyDhE;AAED,MAAM,MAAM,kBAAkB,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Scheduler Infrastructure
3
+ *
4
+ * Defines the scheduler Lambda for auto-publishing scheduled content:
5
+ * - EventBridge rule (every 5 minutes)
6
+ * - Scheduler Lambda (Go)
7
+ * - DynamoDB lock table
8
+ */
9
+ import path from "path";
10
+ export function createScheduler(name, args) {
11
+ const { storage, api } = args;
12
+ // Lock table for distributed scheduler locking
13
+ const schedulerLock = new sst.aws.Dynamo(`${name}SchedulerLock`, {
14
+ fields: {
15
+ pk: "string",
16
+ },
17
+ primaryIndex: { hashKey: "pk" },
18
+ ttl: "ttl",
19
+ });
20
+ const handlerConfig = args.dev
21
+ ? {
22
+ handler: args.dev.handler,
23
+ runtime: "go",
24
+ }
25
+ : {
26
+ bundle: path.join(args.pkgRoot, "lambda/scheduler"),
27
+ handler: "bootstrap",
28
+ runtime: "provided.al2023",
29
+ architecture: "arm64",
30
+ };
31
+ // EventBridge rule (every 5 minutes) with inline scheduler function
32
+ const schedulerCron = new sst.aws.Cron(`${name}SchedulerCron`, {
33
+ schedule: "rate(5 minutes)",
34
+ job: {
35
+ ...handlerConfig,
36
+ timeout: "60 seconds",
37
+ memory: "256 MB",
38
+ environment: {
39
+ CONTENT_TABLE: storage.content.name,
40
+ LOCK_TABLE: schedulerLock.name,
41
+ API_URL: api.api.url,
42
+ },
43
+ permissions: [
44
+ {
45
+ actions: [
46
+ "dynamodb:Query",
47
+ "dynamodb:UpdateItem",
48
+ "dynamodb:PutItem",
49
+ "dynamodb:DeleteItem",
50
+ "dynamodb:GetItem",
51
+ ],
52
+ resources: [
53
+ storage.content.arn,
54
+ $interpolate `${storage.content.arn}/index/*`,
55
+ schedulerLock.arn,
56
+ ],
57
+ },
58
+ ],
59
+ link: [storage.content, schedulerLock],
60
+ },
61
+ });
62
+ return { schedulerLock, schedulerCron };
63
+ }
64
+ //# sourceMappingURL=scheduler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,IAAI,MAAM,MAAM,CAAC;AAcxB,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,IAAmB;IAC/D,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAE9B,+CAA+C;IAC/C,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,eAAe,EAAE;QAC/D,MAAM,EAAE;YACN,EAAE,EAAE,QAAQ;SACb;QACD,YAAY,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;QAC/B,GAAG,EAAE,KAAK;KACX,CAAC,CAAC;IAEH,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG;QAC5B,CAAC,CAAC;YACE,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO;YACzB,OAAO,EAAE,IAAa;SACvB;QACH,CAAC,CAAC;YACE,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,kBAAkB,CAAC;YACnD,OAAO,EAAE,WAAW;YACpB,OAAO,EAAE,iBAA0B;YACnC,YAAY,EAAE,OAAgB;SAC/B,CAAC;IAEN,oEAAoE;IACpE,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,eAAe,EAAE;QAC7D,QAAQ,EAAE,iBAAiB;QAC3B,GAAG,EAAE;YACH,GAAG,aAAa;YAChB,OAAO,EAAE,YAAY;YACrB,MAAM,EAAE,QAAQ;YAChB,WAAW,EAAE;gBACX,aAAa,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI;gBACnC,UAAU,EAAE,aAAa,CAAC,IAAI;gBAC9B,OAAO,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG;aACrB;YACD,WAAW,EAAE;gBACX;oBACE,OAAO,EAAE;wBACP,gBAAgB;wBAChB,qBAAqB;wBACrB,kBAAkB;wBAClB,qBAAqB;wBACrB,kBAAkB;qBACnB;oBACD,SAAS,EAAE;wBACT,OAAO,CAAC,OAAO,CAAC,GAAG;wBACnB,YAAY,CAAA,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,UAAU;wBAC5C,aAAa,CAAC,GAAG;qBAClB;iBACF;aACF;YACD,IAAI,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,aAAa,CAAC;SACvC;KACF,CAAC,CAAC;IAEH,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,CAAC;AAC1C,CAAC"}
package/dist/storage.d.ts CHANGED
@@ -14,6 +14,7 @@ export declare function createStorage(name: string): {
14
14
  blockTypes: sst.aws.Dynamo;
15
15
  adminAudit: sst.aws.Dynamo;
16
16
  relationships: sst.aws.Dynamo;
17
+ siteUsers: sst.aws.Dynamo;
17
18
  contentBucket: sst.aws.Bucket;
18
19
  kvs: aws.cloudfront.KeyValueStore;
19
20
  };
@@ -1 +1 @@
1
- {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM;;;;;;;;;;;;EAgIzC;AAED,MAAM,MAAM,gBAAgB,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC"}
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM;;;;;;;;;;;;;EAiJzC;AAED,MAAM,MAAM,gBAAgB,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC"}
package/dist/storage.js CHANGED
@@ -21,12 +21,15 @@ export function createStorage(name) {
21
21
  lastDraftAtSk: "string",
22
22
  collectionGsiPk: "string",
23
23
  titleSk: "string",
24
+ scheduledGsiPk: "string",
25
+ scheduledGsiSk: "string",
24
26
  },
25
27
  primaryIndex: { hashKey: "pk", rangeKey: "sk" },
26
28
  globalIndexes: {
27
29
  byPublishedDate: { hashKey: "gsiPk", rangeKey: "gsiSk" },
28
30
  byLastDraftAt: { hashKey: "pk", rangeKey: "lastDraftAtSk" },
29
31
  byCollectionTitle: { hashKey: "collectionGsiPk", rangeKey: "titleSk" },
32
+ byScheduledDate: { hashKey: "scheduledGsiPk", rangeKey: "scheduledGsiSk" },
30
33
  },
31
34
  });
32
35
  const draftContent = new sst.aws.Dynamo(`${name}DraftContent`, {
@@ -88,6 +91,18 @@ export function createStorage(name) {
88
91
  byTarget: { hashKey: "targetPk", rangeKey: "targetSk" },
89
92
  },
90
93
  });
94
+ const siteUsers = new sst.aws.Dynamo(`${name}SiteUsers`, {
95
+ fields: {
96
+ pk: "string",
97
+ sk: "string",
98
+ userId: "string",
99
+ },
100
+ primaryIndex: { hashKey: "pk", rangeKey: "sk" },
101
+ globalIndexes: {
102
+ byUserId: { hashKey: "userId", rangeKey: "sk" },
103
+ },
104
+ ttl: "expiresAt",
105
+ });
91
106
  const contentBucket = new sst.aws.Bucket(`${name}ContentBucket`, {
92
107
  versioning: true,
93
108
  access: "cloudfront",
@@ -118,6 +133,7 @@ export function createStorage(name) {
118
133
  blockTypes,
119
134
  adminAudit,
120
135
  relationships,
136
+ siteUsers,
121
137
  contentBucket,
122
138
  kvs,
123
139
  };
@@ -1 +1 @@
1
- {"version":3,"file":"storage.js","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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"}
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "headroom-cms",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Headroom CMS — Serverless headless CMS for AWS, deployed with SST",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/src/api.ts CHANGED
@@ -64,6 +64,8 @@ export function createApi(name: string, args: ApiArgs) {
64
64
  IMAGE_SIGNING_SECRET: image.imageSigningSecret.value,
65
65
  IMAGE_LAMBDA_NAME: image.imageLambda.name,
66
66
  RELATIONSHIPS_TABLE: storage.relationships.name,
67
+ SITE_USERS_TABLE: storage.siteUsers.name,
68
+ SES_FROM_EMAIL: "noreply@headroom.dev",
67
69
  },
68
70
  link: [
69
71
  storage.sites,
@@ -80,6 +82,7 @@ export function createApi(name: string, args: ApiArgs) {
80
82
  webhooks.webhookDeliveryQueue,
81
83
  image.imageSigningSecret,
82
84
  storage.relationships,
85
+ storage.siteUsers,
83
86
  ],
84
87
  permissions: [
85
88
  {
@@ -97,6 +100,7 @@ export function createApi(name: string, args: ApiArgs) {
97
100
  "cognito-idp:AdminCreateUser",
98
101
  "cognito-idp:AdminDeleteUser",
99
102
  "cognito-idp:AdminGetUser",
103
+ "cognito-idp:AdminInitiateAuth",
100
104
  ],
101
105
  resources: [auth.userPool.arn],
102
106
  },
@@ -104,6 +108,10 @@ export function createApi(name: string, args: ApiArgs) {
104
108
  actions: ["lambda:InvokeFunction"],
105
109
  resources: [image.imageLambda.arn],
106
110
  },
111
+ {
112
+ actions: ["ses:SendEmail", "ses:SendRawEmail"],
113
+ resources: ["*"],
114
+ },
107
115
  ],
108
116
  });
109
117
 
package/src/index.ts CHANGED
@@ -13,6 +13,7 @@ import { createWebhooks } from "./webhooks.js";
13
13
  import { createImage } from "./image.js";
14
14
  import { createApi } from "./api.js";
15
15
  import { createCdn } from "./cdn.js";
16
+ import { createScheduler } from "./scheduler.js";
16
17
  import { createAdminSite } from "./admin-site.js";
17
18
 
18
19
  /**
@@ -48,6 +49,7 @@ export type { WebhookResources } from "./webhooks.js";
48
49
  export type { ImageResources } from "./image.js";
49
50
  export type { ApiResources } from "./api.js";
50
51
  export type { CdnResources } from "./cdn.js";
52
+ export type { SchedulerResources } from "./scheduler.js";
51
53
  export type { AdminSiteResources } from "./admin-site.js";
52
54
 
53
55
  export interface HeadroomCMSArgs {
@@ -116,6 +118,8 @@ export interface HeadroomCMSArgs {
116
118
  imageLambdaHandler: string;
117
119
  /** Path to admin UI source, e.g. "packages/admin" */
118
120
  adminPath: string;
121
+ /** Go source path for scheduler Lambda, e.g. "packages/scheduler" */
122
+ schedulerHandler?: string;
119
123
  };
120
124
  }
121
125
 
@@ -175,7 +179,17 @@ export class HeadroomCMS {
175
179
  : undefined,
176
180
  });
177
181
 
178
- // 6. CDN (CloudFront distribution + edge functions)
182
+ // 6. Scheduler (EventBridge cron + Go Lambda + lock table)
183
+ const schedulerResources = createScheduler(name, {
184
+ storage,
185
+ api,
186
+ pkgRoot,
187
+ dev: args.dev?.schedulerHandler
188
+ ? { handler: args.dev.schedulerHandler }
189
+ : undefined,
190
+ });
191
+
192
+ // 7. CDN (CloudFront distribution + edge functions)
179
193
  const cdn = createCdn(name, {
180
194
  api,
181
195
  image,
@@ -186,7 +200,7 @@ export class HeadroomCMS {
186
200
  domain: args.domain,
187
201
  });
188
202
 
189
- // 7. Admin UI (static site)
203
+ // 8. Admin UI (static site)
190
204
  const admin = createAdminSite(name, {
191
205
  api,
192
206
  cdn,
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Scheduler Infrastructure
3
+ *
4
+ * Defines the scheduler Lambda for auto-publishing scheduled content:
5
+ * - EventBridge rule (every 5 minutes)
6
+ * - Scheduler Lambda (Go)
7
+ * - DynamoDB lock table
8
+ */
9
+
10
+ import path from "path";
11
+ import type { StorageResources } from "./storage.js";
12
+ import type { ApiResources } from "./api.js";
13
+
14
+ export interface SchedulerArgs {
15
+ storage: StorageResources;
16
+ api: ApiResources;
17
+ pkgRoot: string;
18
+ dev?: {
19
+ /** Go source path, e.g. "packages/scheduler" */
20
+ handler: string;
21
+ };
22
+ }
23
+
24
+ export function createScheduler(name: string, args: SchedulerArgs) {
25
+ const { storage, api } = args;
26
+
27
+ // Lock table for distributed scheduler locking
28
+ const schedulerLock = new sst.aws.Dynamo(`${name}SchedulerLock`, {
29
+ fields: {
30
+ pk: "string",
31
+ },
32
+ primaryIndex: { hashKey: "pk" },
33
+ ttl: "ttl",
34
+ });
35
+
36
+ const handlerConfig = args.dev
37
+ ? {
38
+ handler: args.dev.handler,
39
+ runtime: "go" as const,
40
+ }
41
+ : {
42
+ bundle: path.join(args.pkgRoot, "lambda/scheduler"),
43
+ handler: "bootstrap",
44
+ runtime: "provided.al2023" as const,
45
+ architecture: "arm64" as const,
46
+ };
47
+
48
+ // EventBridge rule (every 5 minutes) with inline scheduler function
49
+ const schedulerCron = new sst.aws.Cron(`${name}SchedulerCron`, {
50
+ schedule: "rate(5 minutes)",
51
+ job: {
52
+ ...handlerConfig,
53
+ timeout: "60 seconds",
54
+ memory: "256 MB",
55
+ environment: {
56
+ CONTENT_TABLE: storage.content.name,
57
+ LOCK_TABLE: schedulerLock.name,
58
+ API_URL: api.api.url,
59
+ },
60
+ permissions: [
61
+ {
62
+ actions: [
63
+ "dynamodb:Query",
64
+ "dynamodb:UpdateItem",
65
+ "dynamodb:PutItem",
66
+ "dynamodb:DeleteItem",
67
+ "dynamodb:GetItem",
68
+ ],
69
+ resources: [
70
+ storage.content.arn,
71
+ $interpolate`${storage.content.arn}/index/*`,
72
+ schedulerLock.arn,
73
+ ],
74
+ },
75
+ ],
76
+ link: [storage.content, schedulerLock],
77
+ },
78
+ });
79
+
80
+ return { schedulerLock, schedulerCron };
81
+ }
82
+
83
+ export type SchedulerResources = ReturnType<typeof createScheduler>;
package/src/sst-env.d.ts CHANGED
@@ -64,6 +64,10 @@ declare namespace sst {
64
64
  constructor(name: string, args?: any, opts?: any);
65
65
  url: PulumiOutput<string>;
66
66
  }
67
+
68
+ class Cron {
69
+ constructor(name: string, args: any, opts?: any);
70
+ }
67
71
  }
68
72
  }
69
73
 
package/src/storage.ts CHANGED
@@ -23,12 +23,15 @@ export function createStorage(name: string) {
23
23
  lastDraftAtSk: "string",
24
24
  collectionGsiPk: "string",
25
25
  titleSk: "string",
26
+ scheduledGsiPk: "string",
27
+ scheduledGsiSk: "string",
26
28
  },
27
29
  primaryIndex: { hashKey: "pk", rangeKey: "sk" },
28
30
  globalIndexes: {
29
31
  byPublishedDate: { hashKey: "gsiPk", rangeKey: "gsiSk" },
30
32
  byLastDraftAt: { hashKey: "pk", rangeKey: "lastDraftAtSk" },
31
33
  byCollectionTitle: { hashKey: "collectionGsiPk", rangeKey: "titleSk" },
34
+ byScheduledDate: { hashKey: "scheduledGsiPk", rangeKey: "scheduledGsiSk" },
32
35
  },
33
36
  });
34
37
 
@@ -98,6 +101,19 @@ export function createStorage(name: string) {
98
101
  },
99
102
  });
100
103
 
104
+ const siteUsers = new sst.aws.Dynamo(`${name}SiteUsers`, {
105
+ fields: {
106
+ pk: "string",
107
+ sk: "string",
108
+ userId: "string",
109
+ },
110
+ primaryIndex: { hashKey: "pk", rangeKey: "sk" },
111
+ globalIndexes: {
112
+ byUserId: { hashKey: "userId", rangeKey: "sk" },
113
+ },
114
+ ttl: "expiresAt",
115
+ });
116
+
101
117
  const contentBucket = new sst.aws.Bucket(`${name}ContentBucket`, {
102
118
  versioning: true,
103
119
  access: "cloudfront",
@@ -130,6 +146,7 @@ export function createStorage(name: string) {
130
146
  blockTypes,
131
147
  adminAudit,
132
148
  relationships,
149
+ siteUsers,
133
150
  contentBucket,
134
151
  kvs,
135
152
  };
@@ -1 +0,0 @@
1
- import{j as e}from"./tanstack-BO6c-AOu.js";import{u as H,r as x}from"./react-vendor-DNVhVxD7.js";import{o as L,u as q,a7 as B,a8 as _,p as z,a9 as M,aa as V,S as y,D as G,i as $,B as l,j as J,k as K,l as Q,m as W,I as X,n as Y,t as i}from"./index-CwkwXbO-.js";import{u as Z}from"./useAdminResolver-B-_1f6SR.js";import{T as ee,a as se,b,c as p,d as ae,e as j}from"./table-D4rLgOKa.js";import{P as ie,a as te,b as ne}from"./popover-DFInMOpa.js";import{C as re,a as oe,b as le,c as de,d as ce,e as me}from"./command-98iA8Va4.js";import{S as ue,a as he,b as xe,c as pe,d as C}from"./select-Cj54Wt-H.js";import{P as je}from"./plus-2Ds_MoqB.js";import{T as ve}from"./trash-2-CbbWF_O4.js";import"./radix-n1vDIPi6.js";import"./search-DRNC6QB5.js";import"./check-BMpruHpO.js";const fe=[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}],["line",{x1:"19",x2:"19",y1:"8",y2:"14",key:"1bvyxn"}],["line",{x1:"22",x2:"16",y1:"11",y2:"11",key:"1shjgl"}]],ge=L("user-plus",fe);function ke(){const{host:d}=H(),{user:N}=q(),S=B(),{data:A,isLoading:I}=_(d),{data:T}=z(),c=M(d),m=V(d),n=A?.admins??[],E=T?.items??[],r=S==="admin",v=n.map(s=>s.id),{resolve:w}=Z(v),[D,f]=x.useState(!1),[P,g]=x.useState(!1),[u,h]=x.useState("");if(I)return e.jsxs("div",{className:"space-y-2",children:[e.jsx(y,{className:"h-8 w-64"}),Array.from({length:3}).map((s,a)=>e.jsx(y,{className:"h-12 w-full"},a))]});const R=E.filter(s=>!v.includes(s.sub));async function k(s){try{await c.mutateAsync({admins:[...n,{id:s,role:"editor"}]}),i.success("Admin added"),f(!1)}catch(a){i.error("Failed to add admin",{description:a instanceof Error?a.message:void 0})}}async function U(s){if(s.preventDefault(),!!u.trim())try{const a=await m.mutateAsync({email:u.trim()});a.existed?i.success("Existing user added to site"):i.success("Invite email sent",{description:`An invite has been sent to ${a.email}`}),h(""),g(!1)}catch(a){i.error("Failed to invite user",{description:a instanceof Error?a.message:void 0})}}async function O(s){try{await c.mutateAsync({admins:n.filter(a=>a.id!==s)}),i.success("Admin removed")}catch(a){i.error("Failed to remove admin",{description:a instanceof Error?a.message:void 0})}}async function F(s,a){const o=n.map(t=>t.id===s?{...t,role:a}:t);if(!o.some(t=>t.role==="admin")){i.error("At least one admin role is required");return}try{await c.mutateAsync({admins:o}),i.success("Role updated")}catch(t){i.error("Failed to update role",{description:t instanceof Error?t.message:void 0})}}return e.jsxs("div",{children:[e.jsx("h1",{className:"mb-6 text-2xl font-semibold",children:"Admins"}),r&&e.jsxs("div",{className:"mb-6 flex gap-2",children:[e.jsxs(G,{open:P,onOpenChange:s=>{g(s),s||h("")},children:[e.jsx($,{asChild:!0,children:e.jsxs(l,{children:[e.jsx(ge,{className:"mr-2 h-4 w-4"}),"Invite by email"]})}),e.jsxs(J,{children:[e.jsxs(K,{children:[e.jsx(Q,{children:"Invite User to Site"}),e.jsx(W,{className:"sr-only",children:"Send an invite email to add a user to this site"})]}),e.jsxs("form",{onSubmit:U,className:"space-y-4",children:[e.jsx("p",{className:"text-muted-foreground text-sm",children:"Enter an email address. If the user doesn't have an account yet, they'll receive an invite email."}),e.jsx(X,{type:"email",value:u,onChange:s=>h(s.target.value),placeholder:"email@example.com",required:!0}),e.jsx(Y,{children:e.jsx(l,{type:"submit",disabled:m.isPending,children:m.isPending?"Inviting...":"Send Invite"})})]})]})]}),e.jsxs(ie,{open:D,onOpenChange:f,children:[e.jsx(te,{asChild:!0,children:e.jsxs(l,{variant:"outline",children:[e.jsx(je,{className:"mr-2 h-4 w-4"}),"Add existing user"]})}),e.jsx(ne,{className:"w-72 p-0",align:"start",children:e.jsxs(re,{children:[e.jsx(oe,{placeholder:"Search users..."}),e.jsxs(le,{children:[e.jsx(de,{children:"No users found."}),e.jsx(ce,{children:R.map(s=>e.jsx(me,{value:s.email,onSelect:()=>k(s.sub),children:s.email},s.sub))})]})]})})]})]}),n.length===0?e.jsx("p",{className:"text-muted-foreground",children:"No admins configured."}):e.jsxs(ee,{children:[e.jsx(se,{children:e.jsxs(b,{children:[e.jsx(p,{children:"Email"}),e.jsx(p,{children:"Role"}),r&&e.jsx(p,{})]})}),e.jsx(ae,{children:n.map(s=>{const a=s.id===N?.sub;return e.jsxs(b,{children:[e.jsxs(j,{className:"text-sm",children:[w(s.id),a&&e.jsx("span",{className:"ml-2 text-muted-foreground",children:"(you)"})]}),e.jsx(j,{children:r&&!a?e.jsxs(ue,{value:s.role,onValueChange:o=>F(s.id,o),children:[e.jsx(he,{className:"w-28",children:e.jsx(xe,{})}),e.jsxs(pe,{children:[e.jsx(C,{value:"admin",children:"Admin"}),e.jsx(C,{value:"editor",children:"Editor"})]})]}):e.jsx("span",{className:"text-sm capitalize",children:s.role})}),r&&e.jsx(j,{className:"text-right",children:!a&&e.jsx(l,{variant:"ghost",size:"sm",onClick:()=>O(s.id),title:"Remove from site",children:e.jsx(ve,{className:"h-4 w-4"})})})]},s.id)})})]})]})}export{ke as AdminsPage};