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.
- package/admin/assets/AdminsPage-C4tJy6Vj.js +1 -0
- package/admin/assets/AllContentPage-DL0-UlYh.js +1 -0
- package/admin/assets/ApiKeysPage-pZ6nKCZ_.js +1 -0
- package/admin/assets/AuditPage-aVmcP6Ts.js +1 -0
- package/admin/assets/{BlockEditor-C0KaZUHQ.js → BlockEditor-D0Jk8u7w.js} +54 -54
- package/admin/assets/BlockTypeEditPage-DIe2yYEr.js +1 -0
- package/admin/assets/BlockTypesPage-Q7keQKxn.js +1 -0
- package/admin/assets/BulkActionBar-BGDrNwCg.js +1 -0
- package/admin/assets/CollectionEditPage-Bq75MpXk.js +1 -0
- package/admin/assets/CollectionsPage-DDZ-5H7Y.js +1 -0
- package/admin/assets/ContentCreatePage-C3jn0Etf.js +1 -0
- package/admin/assets/ContentEditPage-9tODvFEv.js +2 -0
- package/admin/assets/ContentListPage-VCT6GTCF.js +1 -0
- package/admin/assets/{CustomBlockPreview-CCiZrZhi.js → CustomBlockPreview-f9j4g35U.js} +1 -1
- package/admin/assets/FieldBuilder-p1Y8RubR.js +3 -0
- package/admin/assets/{LoginPage-BlJXP0GH.js → LoginPage-9YUPS1YH.js} +1 -1
- package/admin/assets/MediaField-DJpYbUA8.js +1 -0
- package/admin/assets/MediaPage-BgDRQR21.js +1 -0
- package/admin/assets/SiteSettingsPage-Diy-PauR.js +1 -0
- package/admin/assets/SiteUsersPage-CtVaB0vq.js +1 -0
- package/admin/assets/SitesPage-B-sNyP-Y.js +1 -0
- package/admin/assets/SubmissionDetailPage-DW6QJvAy.js +1 -0
- package/admin/assets/SubmissionEditPage-CxYPdI9-.js +1 -0
- package/admin/assets/SubmissionListPage-BHF82NF3.js +1 -0
- package/admin/assets/TagInput-CrI2BIuz.js +1 -0
- package/admin/assets/TagsPage-BSX5KQvZ.js +1 -0
- package/admin/assets/UsersPage-BCTpWULa.js +1 -0
- package/admin/assets/WebhookEditPage-CQO3nmaT.js +1 -0
- package/admin/assets/WebhooksPage-ByaTlUGU.js +1 -0
- package/admin/assets/{card-DpNr7WTb.js → card-uKxSQehY.js} +1 -1
- package/admin/assets/checkbox-z1kYnX5o.js +1 -0
- package/admin/assets/command-CuWC4GrT.js +1 -0
- package/admin/assets/{core.esm-BtFZvlg0.js → core.esm-B_kcYf6n.js} +2 -2
- package/admin/assets/index-HoCNSqv2.css +1 -0
- package/admin/assets/index-b-u0-VCO.js +18 -0
- package/admin/assets/media-url-DIg_vSyf.js +1 -0
- package/admin/assets/popover-rcnajqN6.js +1 -0
- package/admin/assets/{radix-n1vDIPi6.js → radix-C1kb_NqW.js} +2 -2
- package/admin/assets/react-vendor-C2CvUxFh.js +4 -0
- package/admin/assets/select-BKaV0BO_.js +1 -0
- package/admin/assets/serializeToText-BfR2RCzd.js +2 -0
- package/admin/assets/sortable.esm-BHilUL-2.js +1 -0
- package/admin/assets/{table-D4rLgOKa.js → table-Bozosvl6.js} +1 -1
- package/admin/assets/{tanstack-BO6c-AOu.js → tanstack-Bs3zYPPV.js} +1 -1
- package/admin/assets/textarea-BnjAxJtk.js +1 -0
- package/admin/assets/useAdminResolver-B0ady82Q.js +1 -0
- package/admin/assets/useContent-B2MUK4An.js +1 -0
- package/admin/assets/{useDebouncedValue-Bf8UizjU.js → useDebouncedValue-C-cQUcLG.js} +1 -1
- package/admin/assets/useMedia-CXQpRNYL.js +1 -0
- package/admin/assets/usePageTitle-Do4xyFdL.js +1 -0
- package/admin/assets/useSiteUsers-BfzIdhvs.js +1 -0
- package/admin/assets/{useTags-BB47vbXO.js → useTags-B6FtXCHF.js} +1 -1
- package/admin/assets/{useWebhooks-DS4Ee8Wk.js → useWebhooks-iPRX5y4s.js} +1 -1
- package/admin/favicon-16x16.png +0 -0
- package/admin/favicon-32x32.png +0 -0
- package/admin/index.html +7 -6
- package/admin/sw.js +1 -1
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +8 -0
- package/dist/api.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -2
- package/dist/index.js.map +1 -1
- package/dist/scheduler.d.ts +25 -0
- package/dist/scheduler.d.ts.map +1 -0
- package/dist/scheduler.js +64 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/storage.d.ts +1 -0
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +16 -0
- package/dist/storage.js.map +1 -1
- package/lambda/api/bootstrap +0 -0
- package/lambda/webhook-worker/bootstrap +0 -0
- package/package.json +1 -1
- package/src/api.ts +8 -0
- package/src/index.ts +16 -2
- package/src/scheduler.ts +83 -0
- package/src/sst-env.d.ts +4 -0
- package/src/storage.ts +17 -0
- package/admin/assets/AdminsPage-DYJhlQnA.js +0 -1
- package/admin/assets/AllContentPage-DShBvFru.js +0 -1
- package/admin/assets/ApiKeysPage-DONrd-TJ.js +0 -1
- package/admin/assets/AuditPage-BwhYu96L.js +0 -1
- package/admin/assets/BlockTypeEditPage-BYJfEA6l.js +0 -1
- package/admin/assets/BlockTypesPage-Pf9u78-O.js +0 -1
- package/admin/assets/BulkActionBar-BX-t8fyM.js +0 -1
- package/admin/assets/CollectionEditPage-CQGo9Cbu.js +0 -1
- package/admin/assets/CollectionsPage-D-QTkoW_.js +0 -1
- package/admin/assets/ContentCreatePage-DujNZXXj.js +0 -1
- package/admin/assets/ContentEditPage-DyqgEoAe.js +0 -3
- package/admin/assets/ContentListPage-llAlhZTH.js +0 -1
- package/admin/assets/FieldBuilder-B3-3MTqp.js +0 -3
- package/admin/assets/MediaPage-Cad4n33B.js +0 -1
- package/admin/assets/SiteSettingsPage-xfAm3ZKQ.js +0 -1
- package/admin/assets/SitesPage-DnCiSu23.js +0 -1
- package/admin/assets/TagsPage-DNlaoFCE.js +0 -1
- package/admin/assets/UsersPage-D_nOx6W9.js +0 -1
- package/admin/assets/WebhookEditPage-BUvLl4rY.js +0 -1
- package/admin/assets/WebhooksPage-CG7WC9Bq.js +0 -1
- package/admin/assets/badge-ChZ2DZue.js +0 -1
- package/admin/assets/check-BMpruHpO.js +0 -1
- package/admin/assets/checkbox-VtCfoGic.js +0 -1
- package/admin/assets/command-98iA8Va4.js +0 -1
- package/admin/assets/copy-fXL6Ngxi.js +0 -1
- package/admin/assets/index-CwkwXbO-.js +0 -18
- package/admin/assets/index-FYfbavkE.css +0 -1
- package/admin/assets/plus-2Ds_MoqB.js +0 -1
- package/admin/assets/popover-DFInMOpa.js +0 -1
- package/admin/assets/react-vendor-DNVhVxD7.js +0 -4
- package/admin/assets/search-DRNC6QB5.js +0 -1
- package/admin/assets/select-Cj54Wt-H.js +0 -1
- package/admin/assets/sortable.esm-BUhmZW2_.js +0 -1
- package/admin/assets/trash-2-CbbWF_O4.js +0 -1
- package/admin/assets/use-mobile-Cvl5tIVY.js +0 -1
- package/admin/assets/useAdminResolver-B-_1f6SR.js +0 -1
- package/admin/assets/useContent-Cp41wBYR.js +0 -1
- package/admin/assets/useMedia-DjiNKMOU.js +0 -1
- 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/
|
|
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-
|
|
14
|
-
<link rel="modulepreload" crossorigin href="/assets/react-vendor-
|
|
15
|
-
<link rel="modulepreload" crossorigin href="/assets/tanstack-
|
|
16
|
-
<link rel="modulepreload" crossorigin href="/assets/radix-
|
|
17
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
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
|
|
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;;
|
|
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":"AAAA;;;;;GAKG;AAEH,OAAO,IAAI,MAAM,MAAM,CAAC;AAkBxB,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,IAAa;IACnD,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;IAEhD,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,YAAY,CAAC;YAC7C,OAAO,EAAE,WAAW;YACpB,OAAO,EAAE,iBAA0B;YACnC,YAAY,EAAE,OAAgB;SAC/B,CAAC;IAEN,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,IAAI,KAAK,EAAE;QAC7C,GAAG,aAAa;QAChB,OAAO,EAAE,YAAY;QACrB,GAAG,EAAE;YACH,IAAI,EAAE,KAAK;SACZ;QACD,WAAW,EAAE;YACX,WAAW,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI;YAC/B,aAAa,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI;YACnC,mBAAmB,EAAE,OAAO,CAAC,YAAY,CAAC,IAAI;YAC9C,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI;YACjC,WAAW,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI;YAC/B,iBAAiB,EAAE,OAAO,CAAC,WAAW,CAAC,IAAI;YAC3C,iBAAiB,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI;YAC1C,iBAAiB,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI;YAC1C,cAAc,EAAE,OAAO,CAAC,aAAa,CAAC,IAAI;YAC1C,YAAY,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE;YAC9B,mBAAmB,EAAE,IAAI,CAAC,cAAc,CAAC,EAAE;YAC3C,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG;YACxB,eAAe,EAAE,GAAG,CAAC,eAAe,EAAE,CAAC,IAAI;YAC3C,cAAc,EAAE,QAAQ,CAAC,QAAQ,CAAC,IAAI;YACtC,wBAAwB,EAAE,QAAQ,CAAC,iBAAiB,CAAC,IAAI;YACzD,iBAAiB,EAAE,QAAQ,CAAC,oBAAoB,CAAC,GAAG;YACpD,oBAAoB,EAAE,KAAK,CAAC,kBAAkB,CAAC,KAAK;YACpD,iBAAiB,EAAE,KAAK,CAAC,WAAW,CAAC,IAAI;YACzC,mBAAmB,EAAE,OAAO,CAAC,aAAa,CAAC,IAAI;
|
|
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 {
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
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.
|
|
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
|
-
//
|
|
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":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD;;;;;;;;GAQG;AACH,SAAS,cAAc;IACrB,IAAI,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IACxB,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,cAAc,CAAC,CAAC;QACjE,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7B,OAAO,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;QACpC,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,GAAG;YAAE,MAAM;QAC1B,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;IACD,MAAM,IAAI,KAAK,CACb,uDAAuD;QACvD,yCAAyC,CAC1C,CAAC;AACJ,CAAC;
|
|
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
package/dist/storage.d.ts.map
CHANGED
|
@@ -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
|
|
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
|
};
|
package/dist/storage.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,OAAO,EAAE;QAC/C,MAAM,EAAE;YACN,EAAE,EAAE,QAAQ;YACZ,EAAE,EAAE,QAAQ;SACb;QACD,YAAY,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;KAChD,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,SAAS,EAAE;QACnD,MAAM,EAAE;YACN,EAAE,EAAE,QAAQ;YACZ,EAAE,EAAE,QAAQ;YACZ,KAAK,EAAE,QAAQ;YACf,KAAK,EAAE,QAAQ;YACf,aAAa,EAAE,QAAQ;YACvB,eAAe,EAAE,QAAQ;YACzB,OAAO,EAAE,QAAQ;
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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"}
|
package/lambda/api/bootstrap
CHANGED
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
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.
|
|
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
|
-
//
|
|
203
|
+
// 8. Admin UI (static site)
|
|
190
204
|
const admin = createAdminSite(name, {
|
|
191
205
|
api,
|
|
192
206
|
cdn,
|
package/src/scheduler.ts
ADDED
|
@@ -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
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};
|