@geekity/cms 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2091 -214
- package/admin/components/fields.njk +165 -0
- package/admin/layouts/base.njk +1 -1
- package/admin/layouts/settings-page.njk +26 -0
- package/admin/layouts/shell.njk +17 -3
- package/admin/pages/account/forgot.njk +47 -0
- package/admin/pages/account/login.njk +26 -0
- package/admin/pages/account/reset.njk +38 -0
- package/admin/pages/account/setup.njk +28 -0
- package/admin/pages/appearance/themes.njk +69 -0
- package/admin/pages/comments/all.njk +133 -0
- package/admin/{layouts/dashboard.njk → pages/dashboard/home.njk} +8 -15
- package/admin/{layouts/document-conflict.njk → pages/documents/conflict.njk} +1 -0
- package/admin/pages/documents/editor.njk +196 -0
- package/admin/{layouts/document-list.njk → pages/documents/list.njk} +19 -2
- package/admin/pages/documents/taxonomy.njk +95 -0
- package/admin/pages/federation/followers.njk +238 -0
- package/admin/pages/media/library.njk +160 -0
- package/admin/pages/messages/all.njk +110 -0
- package/admin/{layouts → pages}/placeholder.njk +5 -1
- package/admin/pages/settings/discussion.njk +99 -0
- package/admin/pages/settings/email.njk +203 -0
- package/admin/pages/settings/federation.njk +75 -0
- package/admin/pages/settings/general.njk +29 -0
- package/admin/pages/settings/permalinks.njk +50 -0
- package/admin/pages/settings/reading.njk +72 -0
- package/admin/pages/users/edit.njk +239 -0
- package/admin/pages/users/list.njk +48 -0
- package/admin/pages/users/new.njk +41 -0
- package/admin/static/admin.css +498 -3
- package/admin/static/copy.js +52 -0
- package/admin/static/editor.js +16 -16
- package/admin/static/slug.js +61 -0
- package/dist/admin/accounts.d.ts +413 -0
- package/dist/admin/accounts.d.ts.map +1 -0
- package/dist/admin/accounts.js +680 -0
- package/dist/admin/accounts.js.map +1 -0
- package/dist/admin/appearance.d.ts +80 -0
- package/dist/admin/appearance.d.ts.map +1 -0
- package/dist/admin/appearance.js +136 -0
- package/dist/admin/appearance.js.map +1 -0
- package/dist/admin/comments.d.ts +90 -0
- package/dist/admin/comments.d.ts.map +1 -0
- package/dist/admin/comments.js +244 -0
- package/dist/admin/comments.js.map +1 -0
- package/dist/admin/credentials.d.ts +26 -2
- package/dist/admin/credentials.d.ts.map +1 -1
- package/dist/admin/credentials.js +35 -2
- package/dist/admin/credentials.js.map +1 -1
- package/dist/admin/documents.d.ts +127 -10
- package/dist/admin/documents.d.ts.map +1 -1
- package/dist/admin/documents.js +360 -41
- package/dist/admin/documents.js.map +1 -1
- package/dist/admin/federation.d.ts +151 -50
- package/dist/admin/federation.d.ts.map +1 -1
- package/dist/admin/federation.js +225 -93
- package/dist/admin/federation.js.map +1 -1
- package/dist/admin/formatting.d.ts +20 -0
- package/dist/admin/formatting.d.ts.map +1 -0
- package/dist/admin/formatting.js +72 -0
- package/dist/admin/formatting.js.map +1 -0
- package/dist/admin/headers.d.ts +65 -0
- package/dist/admin/headers.d.ts.map +1 -0
- package/dist/admin/headers.js +104 -0
- package/dist/admin/headers.js.map +1 -0
- package/dist/admin/index.d.ts +38 -12
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +25 -7
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/media.d.ts +168 -0
- package/dist/admin/media.d.ts.map +1 -0
- package/dist/admin/media.js +295 -0
- package/dist/admin/media.js.map +1 -0
- package/dist/admin/menu.d.ts +79 -0
- package/dist/admin/menu.d.ts.map +1 -0
- package/dist/admin/menu.js +126 -0
- package/dist/admin/menu.js.map +1 -0
- package/dist/admin/messages.d.ts +80 -0
- package/dist/admin/messages.d.ts.map +1 -0
- package/dist/admin/messages.js +152 -0
- package/dist/admin/messages.js.map +1 -0
- package/dist/admin/preview.d.ts.map +1 -1
- package/dist/admin/preview.js +31 -7
- package/dist/admin/preview.js.map +1 -1
- package/dist/admin/recovery.d.ts +92 -0
- package/dist/admin/recovery.d.ts.map +1 -0
- package/dist/admin/recovery.js +229 -0
- package/dist/admin/recovery.js.map +1 -0
- package/dist/admin/routes.d.ts +0 -20
- package/dist/admin/routes.d.ts.map +1 -1
- package/dist/admin/routes.js +155 -105
- package/dist/admin/routes.js.map +1 -1
- package/dist/admin/settings-discussion.d.ts +37 -0
- package/dist/admin/settings-discussion.d.ts.map +1 -0
- package/dist/admin/settings-discussion.js +117 -0
- package/dist/admin/settings-discussion.js.map +1 -0
- package/dist/admin/settings-email.d.ts +54 -0
- package/dist/admin/settings-email.d.ts.map +1 -0
- package/dist/admin/settings-email.js +189 -0
- package/dist/admin/settings-email.js.map +1 -0
- package/dist/admin/settings-federation.d.ts +39 -0
- package/dist/admin/settings-federation.d.ts.map +1 -0
- package/dist/admin/settings-federation.js +103 -0
- package/dist/admin/settings-federation.js.map +1 -0
- package/dist/admin/settings-general.d.ts +12 -0
- package/dist/admin/settings-general.d.ts.map +1 -0
- package/dist/admin/settings-general.js +48 -0
- package/dist/admin/settings-general.js.map +1 -0
- package/dist/admin/settings-page.d.ts +102 -0
- package/dist/admin/settings-page.d.ts.map +1 -0
- package/dist/admin/settings-page.js +126 -0
- package/dist/admin/settings-page.js.map +1 -0
- package/dist/admin/settings-pages.d.ts +19 -0
- package/dist/admin/settings-pages.d.ts.map +1 -0
- package/dist/admin/settings-pages.js +33 -0
- package/dist/admin/settings-pages.js.map +1 -0
- package/dist/admin/settings-permalinks.d.ts +16 -0
- package/dist/admin/settings-permalinks.d.ts.map +1 -0
- package/dist/admin/settings-permalinks.js +32 -0
- package/dist/admin/settings-permalinks.js.map +1 -0
- package/dist/admin/settings-reading.d.ts +33 -0
- package/dist/admin/settings-reading.d.ts.map +1 -0
- package/dist/admin/settings-reading.js +48 -0
- package/dist/admin/settings-reading.js.map +1 -0
- package/dist/admin/settings.d.ts +325 -96
- package/dist/admin/settings.d.ts.map +1 -1
- package/dist/admin/settings.js +650 -308
- package/dist/admin/settings.js.map +1 -1
- package/dist/admin/store.d.ts +606 -152
- package/dist/admin/store.d.ts.map +1 -1
- package/dist/admin/store.js +863 -268
- package/dist/admin/store.js.map +1 -1
- package/dist/admin/taxonomy.d.ts +114 -0
- package/dist/admin/taxonomy.d.ts.map +1 -0
- package/dist/admin/taxonomy.js +289 -0
- package/dist/admin/taxonomy.js.map +1 -0
- package/dist/admin/templates.d.ts +44 -14
- package/dist/admin/templates.d.ts.map +1 -1
- package/dist/admin/templates.js +44 -14
- package/dist/admin/templates.js.map +1 -1
- package/dist/admin/throttle.d.ts +84 -0
- package/dist/admin/throttle.d.ts.map +1 -0
- package/dist/admin/throttle.js +143 -0
- package/dist/admin/throttle.js.map +1 -0
- package/dist/admin/uploads.d.ts +28 -2
- package/dist/admin/uploads.d.ts.map +1 -1
- package/dist/admin/uploads.js +43 -4
- package/dist/admin/uploads.js.map +1 -1
- package/dist/admin/users.d.ts +100 -13
- package/dist/admin/users.d.ts.map +1 -1
- package/dist/admin/users.js +412 -39
- package/dist/admin/users.js.map +1 -1
- package/dist/cache.d.ts +141 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +207 -0
- package/dist/cache.js.map +1 -0
- package/dist/cli.d.ts +14 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +424 -21
- package/dist/cli.js.map +1 -1
- package/dist/comments/akismet.d.ts +130 -0
- package/dist/comments/akismet.d.ts.map +1 -0
- package/dist/comments/akismet.js +274 -0
- package/dist/comments/akismet.js.map +1 -0
- package/dist/comments/conversation.d.ts +29 -0
- package/dist/comments/conversation.d.ts.map +1 -0
- package/dist/comments/conversation.js +60 -0
- package/dist/comments/conversation.js.map +1 -0
- package/dist/comments/form.d.ts +75 -0
- package/dist/comments/form.d.ts.map +1 -0
- package/dist/comments/form.js +64 -0
- package/dist/comments/form.js.map +1 -0
- package/dist/comments/index.d.ts +15 -0
- package/dist/comments/index.d.ts.map +1 -0
- package/dist/comments/index.js +9 -0
- package/dist/comments/index.js.map +1 -0
- package/dist/comments/markdown.d.ts +8 -0
- package/dist/comments/markdown.d.ts.map +1 -0
- package/dist/comments/markdown.js +85 -0
- package/dist/comments/markdown.js.map +1 -0
- package/dist/comments/moderate.d.ts +71 -0
- package/dist/comments/moderate.d.ts.map +1 -0
- package/dist/comments/moderate.js +88 -0
- package/dist/comments/moderate.js.map +1 -0
- package/dist/comments/policy.d.ts +57 -0
- package/dist/comments/policy.d.ts.map +1 -0
- package/dist/comments/policy.js +80 -0
- package/dist/comments/policy.js.map +1 -0
- package/dist/comments/records.d.ts +266 -0
- package/dist/comments/records.d.ts.map +1 -0
- package/dist/comments/records.js +487 -0
- package/dist/comments/records.js.map +1 -0
- package/dist/comments/routes.d.ts +58 -0
- package/dist/comments/routes.d.ts.map +1 -0
- package/dist/comments/routes.js +177 -0
- package/dist/comments/routes.js.map +1 -0
- package/dist/comments/submission.d.ts +263 -0
- package/dist/comments/submission.d.ts.map +1 -0
- package/dist/comments/submission.js +241 -0
- package/dist/comments/submission.js.map +1 -0
- package/dist/config.d.ts +190 -5
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +118 -6
- package/dist/config.js.map +1 -1
- package/dist/contact/delivery.d.ts +60 -0
- package/dist/contact/delivery.d.ts.map +1 -0
- package/dist/contact/delivery.js +87 -0
- package/dist/contact/delivery.js.map +1 -0
- package/dist/contact/form.d.ts +130 -0
- package/dist/contact/form.d.ts.map +1 -0
- package/dist/contact/form.js +163 -0
- package/dist/contact/form.js.map +1 -0
- package/dist/contact/index.d.ts +17 -0
- package/dist/contact/index.d.ts.map +1 -0
- package/dist/contact/index.js +13 -0
- package/dist/contact/index.js.map +1 -0
- package/dist/contact/records.d.ts +124 -0
- package/dist/contact/records.d.ts.map +1 -0
- package/dist/contact/records.js +218 -0
- package/dist/contact/records.js.map +1 -0
- package/dist/contact/routes.d.ts +17 -0
- package/dist/contact/routes.d.ts.map +1 -0
- package/dist/contact/routes.js +127 -0
- package/dist/contact/routes.js.map +1 -0
- package/dist/contact/submission.d.ts +103 -0
- package/dist/contact/submission.d.ts.map +1 -0
- package/dist/contact/submission.js +166 -0
- package/dist/contact/submission.js.map +1 -0
- package/dist/content/document.d.ts +7 -2
- package/dist/content/document.d.ts.map +1 -1
- package/dist/content/document.js +1 -0
- package/dist/content/document.js.map +1 -1
- package/dist/content/index.d.ts +7 -2
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/index.js +4 -1
- package/dist/content/index.js.map +1 -1
- package/dist/content/markdown.d.ts.map +1 -1
- package/dist/content/markdown.js +24 -2
- package/dist/content/markdown.js.map +1 -1
- package/dist/content/parser.d.ts.map +1 -1
- package/dist/content/parser.js +11 -4
- package/dist/content/parser.js.map +1 -1
- package/dist/content/save.d.ts +5 -0
- package/dist/content/save.d.ts.map +1 -1
- package/dist/content/save.js +44 -1
- package/dist/content/save.js.map +1 -1
- package/dist/content/schedule.d.ts +125 -0
- package/dist/content/schedule.d.ts.map +1 -0
- package/dist/content/schedule.js +207 -0
- package/dist/content/schedule.js.map +1 -0
- package/dist/content/search.d.ts +64 -0
- package/dist/content/search.d.ts.map +1 -0
- package/dist/content/search.js +136 -0
- package/dist/content/search.js.map +1 -0
- package/dist/content/store.d.ts +202 -7
- package/dist/content/store.d.ts.map +1 -1
- package/dist/content/store.js +374 -67
- package/dist/content/store.js.map +1 -1
- package/dist/content/sync.d.ts +7 -1
- package/dist/content/sync.d.ts.map +1 -1
- package/dist/content/sync.js +18 -10
- package/dist/content/sync.js.map +1 -1
- package/dist/content/time.d.ts +56 -0
- package/dist/content/time.d.ts.map +1 -0
- package/dist/content/time.js +141 -0
- package/dist/content/time.js.map +1 -0
- package/dist/content/writer.d.ts.map +1 -1
- package/dist/content/writer.js +3 -0
- package/dist/content/writer.js.map +1 -1
- package/dist/env.d.ts +58 -4
- package/dist/env.d.ts.map +1 -1
- package/dist/federation/actor.d.ts +95 -41
- package/dist/federation/actor.d.ts.map +1 -1
- package/dist/federation/actor.js +180 -53
- package/dist/federation/actor.js.map +1 -1
- package/dist/federation/article.d.ts +44 -17
- package/dist/federation/article.d.ts.map +1 -1
- package/dist/federation/article.js +98 -46
- package/dist/federation/article.js.map +1 -1
- package/dist/federation/delivery.d.ts +63 -15
- package/dist/federation/delivery.d.ts.map +1 -1
- package/dist/federation/delivery.js +154 -80
- package/dist/federation/delivery.js.map +1 -1
- package/dist/federation/federation.d.ts +22 -17
- package/dist/federation/federation.d.ts.map +1 -1
- package/dist/federation/federation.js +98 -77
- package/dist/federation/federation.js.map +1 -1
- package/dist/federation/followers.d.ts +3 -2
- package/dist/federation/followers.d.ts.map +1 -1
- package/dist/federation/followers.js +6 -5
- package/dist/federation/followers.js.map +1 -1
- package/dist/federation/import-wordpress.d.ts +128 -0
- package/dist/federation/import-wordpress.d.ts.map +1 -0
- package/dist/federation/import-wordpress.js +426 -0
- package/dist/federation/import-wordpress.js.map +1 -0
- package/dist/federation/inbox.d.ts +36 -13
- package/dist/federation/inbox.d.ts.map +1 -1
- package/dist/federation/inbox.js +120 -49
- package/dist/federation/inbox.js.map +1 -1
- package/dist/federation/index.d.ts +22 -10
- package/dist/federation/index.d.ts.map +1 -1
- package/dist/federation/index.js +13 -8
- package/dist/federation/index.js.map +1 -1
- package/dist/federation/keys.d.ts +98 -20
- package/dist/federation/keys.d.ts.map +1 -1
- package/dist/federation/keys.js +269 -39
- package/dist/federation/keys.js.map +1 -1
- package/dist/federation/mount.d.ts +42 -10
- package/dist/federation/mount.d.ts.map +1 -1
- package/dist/federation/mount.js +266 -26
- package/dist/federation/mount.js.map +1 -1
- package/dist/federation/paths.d.ts +23 -35
- package/dist/federation/paths.d.ts.map +1 -1
- package/dist/federation/paths.js +26 -39
- package/dist/federation/paths.js.map +1 -1
- package/dist/federation/records.d.ts +223 -0
- package/dist/federation/records.d.ts.map +1 -0
- package/dist/federation/records.js +506 -0
- package/dist/federation/records.js.map +1 -0
- package/dist/federation/relays.d.ts +114 -0
- package/dist/federation/relays.d.ts.map +1 -0
- package/dist/federation/relays.js +290 -0
- package/dist/federation/relays.js.map +1 -0
- package/dist/federation/replies.d.ts +80 -0
- package/dist/federation/replies.d.ts.map +1 -0
- package/dist/federation/replies.js +166 -0
- package/dist/federation/replies.js.map +1 -0
- package/dist/federation/wordpress.d.ts +131 -0
- package/dist/federation/wordpress.d.ts.map +1 -0
- package/dist/federation/wordpress.js +341 -0
- package/dist/federation/wordpress.js.map +1 -0
- package/dist/files/atomic.d.ts +103 -0
- package/dist/files/atomic.d.ts.map +1 -0
- package/dist/files/atomic.js +150 -0
- package/dist/files/atomic.js.map +1 -0
- package/dist/files/index.d.ts +3 -0
- package/dist/files/index.d.ts.map +1 -0
- package/dist/files/index.js +2 -0
- package/dist/files/index.js.map +1 -0
- package/dist/forms/protection.d.ts +85 -0
- package/dist/forms/protection.d.ts.map +1 -0
- package/dist/forms/protection.js +116 -0
- package/dist/forms/protection.js.map +1 -0
- package/dist/images/icons.d.ts +59 -0
- package/dist/images/icons.d.ts.map +1 -0
- package/dist/images/icons.js +131 -0
- package/dist/images/icons.js.map +1 -0
- package/dist/images/index.d.ts +7 -0
- package/dist/images/index.d.ts.map +1 -0
- package/dist/images/index.js +4 -0
- package/dist/images/index.js.map +1 -0
- package/dist/images/markup.d.ts +47 -0
- package/dist/images/markup.d.ts.map +1 -0
- package/dist/images/markup.js +175 -0
- package/dist/images/markup.js.map +1 -0
- package/dist/images/paths.d.ts +34 -0
- package/dist/images/paths.d.ts.map +1 -0
- package/dist/images/paths.js +41 -0
- package/dist/images/paths.js.map +1 -0
- package/dist/images/variants.d.ts +104 -0
- package/dist/images/variants.d.ts.map +1 -0
- package/dist/images/variants.js +320 -0
- package/dist/images/variants.js.map +1 -0
- package/dist/index.d.ts +123 -19
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +327 -25
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +18 -0
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +34 -3
- package/dist/init.js.map +1 -1
- package/dist/mail/brevo.d.ts +35 -0
- package/dist/mail/brevo.d.ts.map +1 -0
- package/dist/mail/brevo.js +85 -0
- package/dist/mail/brevo.js.map +1 -0
- package/dist/mail/credentials.d.ts +62 -0
- package/dist/mail/credentials.d.ts.map +1 -0
- package/dist/mail/credentials.js +86 -0
- package/dist/mail/credentials.js.map +1 -0
- package/dist/mail/index.d.ts +15 -0
- package/dist/mail/index.d.ts.map +1 -0
- package/dist/mail/index.js +8 -0
- package/dist/mail/index.js.map +1 -0
- package/dist/mail/memory.d.ts +35 -0
- package/dist/mail/memory.d.ts.map +1 -0
- package/dist/mail/memory.js +29 -0
- package/dist/mail/memory.js.map +1 -0
- package/dist/mail/provider.d.ts +80 -0
- package/dist/mail/provider.d.ts.map +1 -0
- package/dist/mail/provider.js +23 -0
- package/dist/mail/provider.js.map +1 -0
- package/dist/mail/service.d.ts +156 -0
- package/dist/mail/service.d.ts.map +1 -0
- package/dist/mail/service.js +265 -0
- package/dist/mail/service.js.map +1 -0
- package/dist/mail/smtp.d.ts +39 -0
- package/dist/mail/smtp.d.ts.map +1 -0
- package/dist/mail/smtp.js +58 -0
- package/dist/mail/smtp.js.map +1 -0
- package/dist/mail/templates.d.ts +91 -0
- package/dist/mail/templates.d.ts.map +1 -0
- package/dist/mail/templates.js +69 -0
- package/dist/mail/templates.js.map +1 -0
- package/dist/notifications/comments.d.ts +66 -0
- package/dist/notifications/comments.d.ts.map +1 -0
- package/dist/notifications/comments.js +151 -0
- package/dist/notifications/comments.js.map +1 -0
- package/dist/notifications/digest.d.ts +135 -0
- package/dist/notifications/digest.d.ts.map +1 -0
- package/dist/notifications/digest.js +287 -0
- package/dist/notifications/digest.js.map +1 -0
- package/dist/notifications/index.d.ts +13 -0
- package/dist/notifications/index.d.ts.map +1 -0
- package/dist/notifications/index.js +8 -0
- package/dist/notifications/index.js.map +1 -0
- package/dist/notifications/links.d.ts +60 -0
- package/dist/notifications/links.d.ts.map +1 -0
- package/dist/notifications/links.js +63 -0
- package/dist/notifications/links.js.map +1 -0
- package/dist/notifications/optouts.d.ts +48 -0
- package/dist/notifications/optouts.d.ts.map +1 -0
- package/dist/notifications/optouts.js +93 -0
- package/dist/notifications/optouts.js.map +1 -0
- package/dist/notifications/preferences.d.ts +158 -0
- package/dist/notifications/preferences.d.ts.map +1 -0
- package/dist/notifications/preferences.js +195 -0
- package/dist/notifications/preferences.js.map +1 -0
- package/dist/notifications/routes.d.ts +28 -0
- package/dist/notifications/routes.d.ts.map +1 -0
- package/dist/notifications/routes.js +184 -0
- package/dist/notifications/routes.js.map +1 -0
- package/dist/notifications/tokens.d.ts +60 -0
- package/dist/notifications/tokens.d.ts.map +1 -0
- package/dist/notifications/tokens.js +125 -0
- package/dist/notifications/tokens.js.map +1 -0
- package/dist/notify.d.ts +84 -0
- package/dist/notify.d.ts.map +1 -0
- package/dist/notify.js +149 -0
- package/dist/notify.js.map +1 -0
- package/dist/web/archive.d.ts +49 -0
- package/dist/web/archive.d.ts.map +1 -0
- package/dist/web/archive.js +59 -0
- package/dist/web/archive.js.map +1 -0
- package/dist/web/assets.d.ts +6 -5
- package/dist/web/assets.d.ts.map +1 -1
- package/dist/web/assets.js +5 -7
- package/dist/web/assets.js.map +1 -1
- package/dist/web/authors.d.ts +143 -0
- package/dist/web/authors.d.ts.map +1 -0
- package/dist/web/authors.js +178 -0
- package/dist/web/authors.js.map +1 -0
- package/dist/web/comments.d.ts +60 -0
- package/dist/web/comments.d.ts.map +1 -0
- package/dist/web/comments.js +207 -0
- package/dist/web/comments.js.map +1 -0
- package/dist/web/context.d.ts +162 -28
- package/dist/web/context.d.ts.map +1 -1
- package/dist/web/context.js +123 -26
- package/dist/web/context.js.map +1 -1
- package/dist/web/conversation.d.ts +209 -0
- package/dist/web/conversation.d.ts.map +1 -0
- package/dist/web/conversation.js +557 -0
- package/dist/web/conversation.js.map +1 -0
- package/dist/web/documents.d.ts +36 -6
- package/dist/web/documents.d.ts.map +1 -1
- package/dist/web/documents.js +52 -10
- package/dist/web/documents.js.map +1 -1
- package/dist/web/feed-atom.d.ts +22 -0
- package/dist/web/feed-atom.d.ts.map +1 -0
- package/dist/web/feed-atom.js +83 -0
- package/dist/web/feed-atom.js.map +1 -0
- package/dist/web/feed-item.d.ts +145 -0
- package/dist/web/feed-item.d.ts.map +1 -0
- package/dist/web/feed-item.js +120 -0
- package/dist/web/feed-item.js.map +1 -0
- package/dist/web/feed-json.d.ts +79 -0
- package/dist/web/feed-json.d.ts.map +1 -0
- package/dist/web/feed-json.js +53 -0
- package/dist/web/feed-json.js.map +1 -0
- package/dist/web/feed-rss.d.ts +26 -0
- package/dist/web/feed-rss.d.ts.map +1 -0
- package/dist/web/feed-rss.js +203 -0
- package/dist/web/feed-rss.js.map +1 -0
- package/dist/web/feed-source.d.ts +244 -0
- package/dist/web/feed-source.d.ts.map +1 -0
- package/dist/web/feed-source.js +201 -0
- package/dist/web/feed-source.js.map +1 -0
- package/dist/web/feed-xml.d.ts +63 -0
- package/dist/web/feed-xml.d.ts.map +1 -0
- package/dist/web/feed-xml.js +116 -0
- package/dist/web/feed-xml.js.map +1 -0
- package/dist/web/feeds.d.ts +31 -96
- package/dist/web/feeds.d.ts.map +1 -1
- package/dist/web/feeds.js +94 -198
- package/dist/web/feeds.js.map +1 -1
- package/dist/web/health.d.ts +31 -0
- package/dist/web/health.d.ts.map +1 -0
- package/dist/web/health.js +44 -0
- package/dist/web/health.js.map +1 -0
- package/dist/web/index.d.ts +30 -10
- package/dist/web/index.d.ts.map +1 -1
- package/dist/web/index.js +18 -7
- package/dist/web/index.js.map +1 -1
- package/dist/web/navigation.d.ts +73 -0
- package/dist/web/navigation.d.ts.map +1 -0
- package/dist/web/navigation.js +110 -0
- package/dist/web/navigation.js.map +1 -0
- package/dist/web/negotiate.d.ts +9 -0
- package/dist/web/negotiate.d.ts.map +1 -1
- package/dist/web/negotiate.js +6 -1
- package/dist/web/negotiate.js.map +1 -1
- package/dist/web/recent.d.ts +43 -0
- package/dist/web/recent.d.ts.map +1 -0
- package/dist/web/recent.js +37 -0
- package/dist/web/recent.js.map +1 -0
- package/dist/web/render.d.ts +197 -9
- package/dist/web/render.d.ts.map +1 -1
- package/dist/web/render.js +334 -17
- package/dist/web/render.js.map +1 -1
- package/dist/web/routes.d.ts +25 -8
- package/dist/web/routes.d.ts.map +1 -1
- package/dist/web/routes.js +845 -93
- package/dist/web/routes.js.map +1 -1
- package/dist/web/sanitize.d.ts +19 -0
- package/dist/web/sanitize.d.ts.map +1 -0
- package/dist/web/sanitize.js +272 -0
- package/dist/web/sanitize.js.map +1 -0
- package/dist/web/search.d.ts +79 -0
- package/dist/web/search.d.ts.map +1 -0
- package/dist/web/search.js +94 -0
- package/dist/web/search.js.map +1 -0
- package/dist/web/sitemap.d.ts +120 -0
- package/dist/web/sitemap.d.ts.map +1 -0
- package/dist/web/sitemap.js +199 -0
- package/dist/web/sitemap.js.map +1 -0
- package/dist/web/taxonomy.d.ts +152 -0
- package/dist/web/taxonomy.d.ts.map +1 -0
- package/dist/web/taxonomy.js +237 -0
- package/dist/web/taxonomy.js.map +1 -0
- package/dist/web/templates.d.ts +54 -16
- package/dist/web/templates.d.ts.map +1 -1
- package/dist/web/templates.js +109 -28
- package/dist/web/templates.js.map +1 -1
- package/dist/web/themes.d.ts +205 -0
- package/dist/web/themes.d.ts.map +1 -0
- package/dist/web/themes.js +277 -0
- package/dist/web/themes.js.map +1 -0
- package/dist/webmention/discovery.d.ts +51 -0
- package/dist/webmention/discovery.d.ts.map +1 -0
- package/dist/webmention/discovery.js +176 -0
- package/dist/webmention/discovery.js.map +1 -0
- package/dist/webmention/html.d.ts +71 -0
- package/dist/webmention/html.d.ts.map +1 -0
- package/dist/webmention/html.js +285 -0
- package/dist/webmention/html.js.map +1 -0
- package/dist/webmention/index.d.ts +12 -0
- package/dist/webmention/index.d.ts.map +1 -0
- package/dist/webmention/index.js +8 -0
- package/dist/webmention/index.js.map +1 -0
- package/dist/webmention/links.d.ts +18 -0
- package/dist/webmention/links.d.ts.map +1 -0
- package/dist/webmention/links.js +64 -0
- package/dist/webmention/links.js.map +1 -0
- package/dist/webmention/microformats.d.ts +93 -0
- package/dist/webmention/microformats.d.ts.map +1 -0
- package/dist/webmention/microformats.js +376 -0
- package/dist/webmention/microformats.js.map +1 -0
- package/dist/webmention/receive.d.ts +141 -0
- package/dist/webmention/receive.d.ts.map +1 -0
- package/dist/webmention/receive.js +264 -0
- package/dist/webmention/receive.js.map +1 -0
- package/dist/webmention/routes.d.ts +37 -0
- package/dist/webmention/routes.d.ts.map +1 -0
- package/dist/webmention/routes.js +75 -0
- package/dist/webmention/routes.js.map +1 -0
- package/dist/webmention/service.d.ts +94 -0
- package/dist/webmention/service.d.ts.map +1 -0
- package/dist/webmention/service.js +207 -0
- package/dist/webmention/service.js.map +1 -0
- package/package.json +11 -6
- package/templates/site/content/_data/site.json +1 -0
- package/templates/site/content/posts/2026-01-01-hello-world.md +5 -3
- package/templates/site/geekity.config.ts +11 -1
- package/templates/site/tsconfig.json +1 -1
- package/themes/default/README.md +1096 -50
- package/themes/default/layouts/404.njk +2 -3
- package/themes/default/layouts/author.njk +37 -0
- package/themes/default/layouts/base.njk +172 -31
- package/themes/default/layouts/category.njk +27 -0
- package/themes/default/layouts/front-page.njk +57 -0
- package/themes/default/layouts/home.njk +17 -1
- package/themes/default/layouts/page.njk +57 -5
- package/themes/default/layouts/post.njk +78 -19
- package/themes/default/layouts/search.njk +57 -0
- package/themes/default/layouts/tag.njk +3 -6
- package/themes/default/mail/comment-digest.html.njk +37 -0
- package/themes/default/mail/comment-digest.subject.njk +3 -0
- package/themes/default/mail/comment-digest.txt.njk +40 -0
- package/themes/default/mail/comment-pending.html.njk +27 -0
- package/themes/default/mail/comment-pending.subject.njk +2 -0
- package/themes/default/mail/comment-pending.txt.njk +24 -0
- package/themes/default/mail/comment-reply.html.njk +21 -0
- package/themes/default/mail/comment-reply.subject.njk +2 -0
- package/themes/default/mail/comment-reply.txt.njk +22 -0
- package/themes/default/mail/contact-message.html.njk +24 -0
- package/themes/default/mail/contact-message.subject.njk +5 -0
- package/themes/default/mail/contact-message.txt.njk +20 -0
- package/themes/default/mail/password-changed.html.njk +18 -0
- package/themes/default/mail/password-changed.subject.njk +2 -0
- package/themes/default/mail/password-changed.txt.njk +17 -0
- package/themes/default/mail/password-reset.html.njk +22 -0
- package/themes/default/mail/password-reset.subject.njk +2 -0
- package/themes/default/mail/password-reset.txt.njk +18 -0
- package/themes/default/mail/test.html.njk +14 -0
- package/themes/default/mail/test.subject.njk +2 -0
- package/themes/default/mail/test.txt.njk +12 -0
- package/themes/default/partials/archive.njk +27 -0
- package/themes/default/partials/bio.njk +77 -0
- package/themes/default/partials/comment-form.njk +109 -0
- package/themes/default/partials/contact-form.njk +88 -0
- package/themes/default/partials/conversation.njk +139 -0
- package/themes/default/partials/feeds.njk +26 -0
- package/themes/default/partials/jsonld.njk +120 -0
- package/themes/default/partials/pagination.njk +12 -6
- package/themes/default/partials/post-list.njk +51 -18
- package/themes/default/partials/search-form.njk +17 -0
- package/themes/default/partials/tags.njk +26 -5
- package/themes/default/static/highlight.js +4 -0
- package/themes/default/static/style.css +1119 -194
- package/themes/default/theme.json +5 -0
- package/admin/layouts/document-editor.njk +0 -167
- package/admin/layouts/federation.njk +0 -145
- package/admin/layouts/login.njk +0 -23
- package/admin/layouts/settings.njk +0 -116
- package/admin/layouts/setup.njk +0 -27
- package/admin/layouts/users.njk +0 -91
- /package/admin/{layouts/_flash.njk → components/flash.njk} +0 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { createTemplateEnvironment, useThemeDirs } from '../web/templates.js';
|
|
2
|
+
import { findThemeFile } from '../web/themes.js';
|
|
3
|
+
/** Which files a named message is built from, relative to a theme directory. */
|
|
4
|
+
export function mailTemplateFiles(name) {
|
|
5
|
+
return {
|
|
6
|
+
subject: `mail/${name}.subject.njk`,
|
|
7
|
+
text: `mail/${name}.txt.njk`,
|
|
8
|
+
html: `mail/${name}.html.njk`,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
/** Build the mail templates for one site. */
|
|
12
|
+
export function createMailTemplates(options) {
|
|
13
|
+
// The same environment the theme is rendered through, so a message has the
|
|
14
|
+
// same `date`, `url` and `absoluteUrl` filters a page does and a site does
|
|
15
|
+
// not have to learn a second set of rules to write one.
|
|
16
|
+
const environment = createTemplateEnvironment({
|
|
17
|
+
themeDirs: options.themes.current().dirs,
|
|
18
|
+
baseUrl: options.baseUrl,
|
|
19
|
+
...(options.noCache === undefined ? {} : { noCache: options.noCache }),
|
|
20
|
+
});
|
|
21
|
+
// The same again with autoescaping off, for the two halves of a message that
|
|
22
|
+
// are not HTML. Built here rather than by unescaping afterwards, because
|
|
23
|
+
// there is no way to tell an `&` the template meant from one it did not.
|
|
24
|
+
const plainEnvironment = createTemplateEnvironment({
|
|
25
|
+
themeDirs: options.themes.current().dirs,
|
|
26
|
+
baseUrl: options.baseUrl,
|
|
27
|
+
autoescape: false,
|
|
28
|
+
...(options.noCache === undefined ? {} : { noCache: options.noCache }),
|
|
29
|
+
});
|
|
30
|
+
/**
|
|
31
|
+
* The theme this message is being written in, with both environments pointed
|
|
32
|
+
* at it.
|
|
33
|
+
*
|
|
34
|
+
* Asked per message rather than held, for the reason a page asks per render:
|
|
35
|
+
* a theme chosen a minute ago is the one the next message should come from.
|
|
36
|
+
* The directories it hands back are what `present` then asks about, so which
|
|
37
|
+
* halves of a message exist is the same question as which file a render
|
|
38
|
+
* would read.
|
|
39
|
+
*/
|
|
40
|
+
function themeDirs() {
|
|
41
|
+
const dirs = options.themes.current().dirs;
|
|
42
|
+
useThemeDirs(environment, dirs);
|
|
43
|
+
useThemeDirs(plainEnvironment, dirs);
|
|
44
|
+
return dirs;
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
environment,
|
|
48
|
+
plainEnvironment,
|
|
49
|
+
render(name, context = {}) {
|
|
50
|
+
const files = mailTemplateFiles(name);
|
|
51
|
+
const searchPath = themeDirs();
|
|
52
|
+
/** Whether any theme on the search path has that template. */
|
|
53
|
+
const present = (template) => findThemeFile(searchPath, template) !== undefined;
|
|
54
|
+
if (!present(files.text)) {
|
|
55
|
+
throw new Error(`There is no mail template ${files.text} in the site theme or in the packaged one.`);
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
// A subject is a header, and a header is one line: whatever the
|
|
59
|
+
// template did with whitespace, what goes out is a single line.
|
|
60
|
+
subject: present(files.subject)
|
|
61
|
+
? plainEnvironment.render(files.subject, context).replace(/\s+/g, ' ').trim()
|
|
62
|
+
: '',
|
|
63
|
+
text: plainEnvironment.render(files.text, context),
|
|
64
|
+
...(present(files.html) ? { html: environment.render(files.html, context) } : {}),
|
|
65
|
+
};
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/mail/templates.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,yBAAyB,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AA4CjD,gFAAgF;AAChF,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO;QACL,OAAO,EAAE,QAAQ,IAAI,cAAc;QACnC,IAAI,EAAE,QAAQ,IAAI,UAAU;QAC5B,IAAI,EAAE,QAAQ,IAAI,WAAW;KAC9B,CAAC;AACJ,CAAC;AAkDD,6CAA6C;AAC7C,MAAM,UAAU,mBAAmB,CAAC,OAAmC;IACrE,2EAA2E;IAC3E,2EAA2E;IAC3E,wDAAwD;IACxD,MAAM,WAAW,GAAG,yBAAyB,CAAC;QAC5C,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,IAAI;QACxC,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;KACvE,CAAC,CAAC;IAEH,6EAA6E;IAC7E,yEAAyE;IACzE,6EAA6E;IAC7E,MAAM,gBAAgB,GAAG,yBAAyB,CAAC;QACjD,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,IAAI;QACxC,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,UAAU,EAAE,KAAK;QACjB,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;KACvE,CAAC,CAAC;IAEH;;;;;;;;;OASG;IACH,SAAS,SAAS;QAChB,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC;QAC3C,YAAY,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QAChC,YAAY,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;QACrC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO;QACL,WAAW;QACX,gBAAgB;QAEhB,MAAM,CAAC,IAAI,EAAE,OAAO,GAAG,EAAE;YACvB,MAAM,KAAK,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YACtC,MAAM,UAAU,GAAG,SAAS,EAAE,CAAC;YAE/B,8DAA8D;YAC9D,MAAM,OAAO,GAAG,CAAC,QAAgB,EAAW,EAAE,CAC5C,aAAa,CAAC,UAAU,EAAE,QAAQ,CAAC,KAAK,SAAS,CAAC;YAEpD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBACzB,MAAM,IAAI,KAAK,CACb,6BAA6B,KAAK,CAAC,IAAI,4CAA4C,CACpF,CAAC;YACJ,CAAC;YAED,OAAO;gBACL,gEAAgE;gBAChE,gEAAgE;gBAChE,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC;oBAC7B,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE;oBAC7E,CAAC,CAAC,EAAE;gBACN,IAAI,EAAE,gBAAgB,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC;gBAClD,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAClF,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { AdminStore, PostComment } from '../admin/store.ts';
|
|
2
|
+
import type { ResolvedConfig } from '../config.ts';
|
|
3
|
+
import type { ContentStore } from '../content/store.ts';
|
|
4
|
+
import type { MailService } from '../mail/service.ts';
|
|
5
|
+
/**
|
|
6
|
+
* The two messages a comment sets off, and the rules about who gets them.
|
|
7
|
+
*
|
|
8
|
+
* Both go through the mail service and nothing else (TASK-53), so a site with
|
|
9
|
+
* no provider sends nothing and every path through here still works. Neither
|
|
10
|
+
* is awaited by the request that caused it: a comment is stored, a page is
|
|
11
|
+
* redirected to, and the message goes out behind that.
|
|
12
|
+
*
|
|
13
|
+
* **The moderation notice.** A comment or a webmention has entered the queue,
|
|
14
|
+
* so everyone who has an address and has not turned the notice off is told,
|
|
15
|
+
* with the words themselves and three signed links that approve, file as spam
|
|
16
|
+
* or delete it without a login. It goes out for `pending` and nothing else,
|
|
17
|
+
* which is the whole of the "not for spam" rule: a comment Akismet filed as
|
|
18
|
+
* spam is nobody's decision to make today, and one it said to discard was
|
|
19
|
+
* never stored at all.
|
|
20
|
+
*
|
|
21
|
+
* **The reply notice.** Somebody ticked "tell me about replies" when they
|
|
22
|
+
* commented, and a reply to that comment has just been approved. That is the
|
|
23
|
+
* only moment it goes: an unapproved reply is not something a stranger should
|
|
24
|
+
* be emailed the text of, and a moderator should be able to delete a nasty one
|
|
25
|
+
* before anybody hears about it.
|
|
26
|
+
*
|
|
27
|
+
* Three things stop it. The address is missing, the address has unsubscribed,
|
|
28
|
+
* or the reply is by the very person who would be told — nobody needs an email
|
|
29
|
+
* about their own words.
|
|
30
|
+
*/
|
|
31
|
+
/** The message an admin gets when something is waiting. */
|
|
32
|
+
export declare const COMMENT_PENDING_TEMPLATE = "comment-pending";
|
|
33
|
+
/** The message a commenter gets when a reply to them is approved. */
|
|
34
|
+
export declare const COMMENT_REPLY_TEMPLATE = "comment-reply";
|
|
35
|
+
/** The event name the users screen switches, from the registry. */
|
|
36
|
+
export declare const COMMENTS_NOTIFICATION = "comments";
|
|
37
|
+
/** What {@link createCommentNotifier} needs. */
|
|
38
|
+
export interface CreateCommentNotifierOptions {
|
|
39
|
+
/** The comment index, which is what a parent comment is looked up in. */
|
|
40
|
+
admin: AdminStore;
|
|
41
|
+
/** The content index, for the post's title. */
|
|
42
|
+
store: ContentStore;
|
|
43
|
+
/** The one door out for email. */
|
|
44
|
+
mail: MailService;
|
|
45
|
+
/**
|
|
46
|
+
* Config after defaults: the base URL the links are absolute against, the
|
|
47
|
+
* data directory the signing secret and the opt-outs live in, and the clock.
|
|
48
|
+
*/
|
|
49
|
+
config: Pick<ResolvedConfig, 'baseUrl' | 'dataDir' | 'now'>;
|
|
50
|
+
}
|
|
51
|
+
/** Tells people about comments. Never throws, and never waits on a provider. */
|
|
52
|
+
export interface CommentNotifier {
|
|
53
|
+
/**
|
|
54
|
+
* A comment has been stored. Tells the moderators when, and only when, it is
|
|
55
|
+
* waiting for one of them.
|
|
56
|
+
*/
|
|
57
|
+
pending(comment: PostComment): void;
|
|
58
|
+
/**
|
|
59
|
+
* A comment has been approved. Tells whoever it answers, when they asked to
|
|
60
|
+
* be told and are still listening.
|
|
61
|
+
*/
|
|
62
|
+
replyApproved(reply: PostComment): void;
|
|
63
|
+
}
|
|
64
|
+
/** Build the notifier for one site. */
|
|
65
|
+
export declare function createCommentNotifier(options: CreateCommentNotifierOptions): CommentNotifier;
|
|
66
|
+
//# sourceMappingURL=comments.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comments.d.ts","sourceRoot":"","sources":["../../src/notifications/comments.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAKtD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,2DAA2D;AAC3D,eAAO,MAAM,wBAAwB,oBAAoB,CAAC;AAE1D,qEAAqE;AACrE,eAAO,MAAM,sBAAsB,kBAAkB,CAAC;AAEtD,mEAAmE;AACnE,eAAO,MAAM,qBAAqB,aAAa,CAAC;AAEhD,gDAAgD;AAChD,MAAM,WAAW,4BAA4B;IAC3C,yEAAyE;IACzE,KAAK,EAAE,UAAU,CAAC;IAClB,+CAA+C;IAC/C,KAAK,EAAE,YAAY,CAAC;IACpB,kCAAkC;IAClC,IAAI,EAAE,WAAW,CAAC;IAClB;;;OAGG;IACH,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,SAAS,GAAG,SAAS,GAAG,KAAK,CAAC,CAAC;CAC7D;AAED,gFAAgF;AAChF,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;IACpC;;;OAGG;IACH,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;CACzC;AAED,uCAAuC;AACvC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,4BAA4B,GAAG,eAAe,CA6G5F"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { listUsers } from '../admin/accounts.js';
|
|
2
|
+
import { commentAnchor } from '../web/conversation.js';
|
|
3
|
+
import { MODERATION_ACTIONS } from '../comments/moderate.js';
|
|
4
|
+
import { moderationLink, unsubscribeLink } from './links.js';
|
|
5
|
+
import { hasOptedOut } from './optouts.js';
|
|
6
|
+
import { isBatchedMode, notificationMode, notificationRecipients } from './preferences.js';
|
|
7
|
+
/**
|
|
8
|
+
* The two messages a comment sets off, and the rules about who gets them.
|
|
9
|
+
*
|
|
10
|
+
* Both go through the mail service and nothing else (TASK-53), so a site with
|
|
11
|
+
* no provider sends nothing and every path through here still works. Neither
|
|
12
|
+
* is awaited by the request that caused it: a comment is stored, a page is
|
|
13
|
+
* redirected to, and the message goes out behind that.
|
|
14
|
+
*
|
|
15
|
+
* **The moderation notice.** A comment or a webmention has entered the queue,
|
|
16
|
+
* so everyone who has an address and has not turned the notice off is told,
|
|
17
|
+
* with the words themselves and three signed links that approve, file as spam
|
|
18
|
+
* or delete it without a login. It goes out for `pending` and nothing else,
|
|
19
|
+
* which is the whole of the "not for spam" rule: a comment Akismet filed as
|
|
20
|
+
* spam is nobody's decision to make today, and one it said to discard was
|
|
21
|
+
* never stored at all.
|
|
22
|
+
*
|
|
23
|
+
* **The reply notice.** Somebody ticked "tell me about replies" when they
|
|
24
|
+
* commented, and a reply to that comment has just been approved. That is the
|
|
25
|
+
* only moment it goes: an unapproved reply is not something a stranger should
|
|
26
|
+
* be emailed the text of, and a moderator should be able to delete a nasty one
|
|
27
|
+
* before anybody hears about it.
|
|
28
|
+
*
|
|
29
|
+
* Three things stop it. The address is missing, the address has unsubscribed,
|
|
30
|
+
* or the reply is by the very person who would be told — nobody needs an email
|
|
31
|
+
* about their own words.
|
|
32
|
+
*/
|
|
33
|
+
/** The message an admin gets when something is waiting. */
|
|
34
|
+
export const COMMENT_PENDING_TEMPLATE = 'comment-pending';
|
|
35
|
+
/** The message a commenter gets when a reply to them is approved. */
|
|
36
|
+
export const COMMENT_REPLY_TEMPLATE = 'comment-reply';
|
|
37
|
+
/** The event name the users screen switches, from the registry. */
|
|
38
|
+
export const COMMENTS_NOTIFICATION = 'comments';
|
|
39
|
+
/** Build the notifier for one site. */
|
|
40
|
+
export function createCommentNotifier(options) {
|
|
41
|
+
const { admin, store, mail, config } = options;
|
|
42
|
+
/** The post a comment is on, as a message names it. */
|
|
43
|
+
function postOf(comment) {
|
|
44
|
+
const document = store.getBySlug(comment.slug);
|
|
45
|
+
return {
|
|
46
|
+
title: document?.title ?? comment.slug,
|
|
47
|
+
url: absolute(comment.permalink, config.baseUrl),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/** What a message says about the comment itself. */
|
|
51
|
+
function commentIn(comment) {
|
|
52
|
+
return {
|
|
53
|
+
author: comment.author.name,
|
|
54
|
+
// The website they gave, which is a thing a moderator judges a comment
|
|
55
|
+
// by. Never their email: the message goes to a moderator, but it also
|
|
56
|
+
// goes through a third party's servers, and the address is not needed to
|
|
57
|
+
// decide anything.
|
|
58
|
+
website: comment.author.url,
|
|
59
|
+
source: comment.source,
|
|
60
|
+
kind: comment.kind,
|
|
61
|
+
text: comment.content.markdown,
|
|
62
|
+
html: comment.content.html,
|
|
63
|
+
submitted: comment.submitted,
|
|
64
|
+
// Where it came from, for a webmention: the page that linked here.
|
|
65
|
+
url: comment.url,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
pending(comment) {
|
|
70
|
+
if (comment.status !== 'pending')
|
|
71
|
+
return;
|
|
72
|
+
// Asked before anything else, so a site that sends no mail never mints a
|
|
73
|
+
// signing secret it would have no use for.
|
|
74
|
+
if (!mail.configured())
|
|
75
|
+
return;
|
|
76
|
+
// Everybody who wants the notice as it happens. A user on an hourly or
|
|
77
|
+
// daily digest is deliberately not written to here: the whole of what
|
|
78
|
+
// choosing a window means is that this moment is not one of the moments
|
|
79
|
+
// they hear about (TASK-60), and `createCommentDigest` writes to them
|
|
80
|
+
// instead, from the queue as it stands when their window comes up.
|
|
81
|
+
const recipients = notificationRecipients(listUsers(config.dataDir), COMMENTS_NOTIFICATION).filter((recipient) => !isBatchedMode(notificationMode(recipient.user, COMMENTS_NOTIFICATION)));
|
|
82
|
+
if (recipients.length === 0)
|
|
83
|
+
return;
|
|
84
|
+
const context = { dataDir: config.dataDir, baseUrl: config.baseUrl, now: config.now() };
|
|
85
|
+
const actions = MODERATION_ACTIONS.map((action) => ({
|
|
86
|
+
action,
|
|
87
|
+
label: action === 'approve' ? 'Approve' : action === 'spam' ? 'Spam' : 'Delete',
|
|
88
|
+
url: moderationLink(context, comment.id, action),
|
|
89
|
+
}));
|
|
90
|
+
const data = {
|
|
91
|
+
comment: commentIn(comment),
|
|
92
|
+
post: postOf(comment),
|
|
93
|
+
actions,
|
|
94
|
+
queueUrl: absolute('/admin/comments', config.baseUrl),
|
|
95
|
+
};
|
|
96
|
+
for (const recipient of recipients) {
|
|
97
|
+
// One message each rather than one with everybody on it: a moderator's
|
|
98
|
+
// address is not something to show the other moderators, and a message
|
|
99
|
+
// per person is what lets a later version say something different to
|
|
100
|
+
// each of them.
|
|
101
|
+
void mail.send({ to: recipient.email, template: COMMENT_PENDING_TEMPLATE, data });
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
replyApproved(reply) {
|
|
105
|
+
if (reply.status !== 'approved' || reply.inReplyTo === null)
|
|
106
|
+
return;
|
|
107
|
+
if (!mail.configured())
|
|
108
|
+
return;
|
|
109
|
+
const parent = admin.getComment(reply.inReplyTo);
|
|
110
|
+
if (parent === undefined || !parent.notify)
|
|
111
|
+
return;
|
|
112
|
+
const address = parent.author.email;
|
|
113
|
+
if (address === null || address === '')
|
|
114
|
+
return;
|
|
115
|
+
// Nobody wants an email about their own reply, and a thread of two
|
|
116
|
+
// people talking would otherwise send one on every message.
|
|
117
|
+
if (address.toLowerCase() === (reply.author.email ?? '').toLowerCase())
|
|
118
|
+
return;
|
|
119
|
+
if (hasOptedOut(config.dataDir, address))
|
|
120
|
+
return;
|
|
121
|
+
const context = { dataDir: config.dataDir, baseUrl: config.baseUrl, now: config.now() };
|
|
122
|
+
const post = postOf(reply);
|
|
123
|
+
void mail.send({
|
|
124
|
+
to: address,
|
|
125
|
+
template: COMMENT_REPLY_TEMPLATE,
|
|
126
|
+
data: {
|
|
127
|
+
reply: {
|
|
128
|
+
...commentIn(reply),
|
|
129
|
+
url: reply.url ?? `${post.url}#${commentAnchor(reply.id)}`,
|
|
130
|
+
},
|
|
131
|
+
comment: {
|
|
132
|
+
...commentIn(parent),
|
|
133
|
+
url: parent.url ?? `${post.url}#${commentAnchor(parent.id)}`,
|
|
134
|
+
},
|
|
135
|
+
post,
|
|
136
|
+
unsubscribeUrl: unsubscribeLink(context, address),
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
/** A site-root path as an absolute URL. */
|
|
143
|
+
function absolute(pathname, baseUrl) {
|
|
144
|
+
try {
|
|
145
|
+
return new URL(pathname, baseUrl).href;
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
return pathname;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=comments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comments.js","sourceRoot":"","sources":["../../src/notifications/comments.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import type { AdminStore } from '../admin/store.ts';
|
|
2
|
+
import type { ResolvedConfig } from '../config.ts';
|
|
3
|
+
import type { ContentStore } from '../content/store.ts';
|
|
4
|
+
import type { MailService } from '../mail/service.ts';
|
|
5
|
+
/**
|
|
6
|
+
* One message a window instead of one message a comment.
|
|
7
|
+
*
|
|
8
|
+
* TASK-55 emails every moderator the moment something enters the queue, which
|
|
9
|
+
* is right for a quiet site and wrong for a spam wave that Akismet let
|
|
10
|
+
* through. A user who has chosen `hourly` or `daily` on `/admin/users` is sent
|
|
11
|
+
* nothing when a comment arrives; instead this sends them one message per
|
|
12
|
+
* window listing everything still waiting, each item with its own approve,
|
|
13
|
+
* spam and delete links.
|
|
14
|
+
*
|
|
15
|
+
* Three decisions hold the whole thing up:
|
|
16
|
+
*
|
|
17
|
+
* - **A digest is derived, not queued.** It is built from what
|
|
18
|
+
* `admin.listComments({ status: 'pending' })` says right now, so an item
|
|
19
|
+
* somebody approved before the run is simply absent and there is no queue to
|
|
20
|
+
* keep true across a restart, a crash or a `geekity rebuild`. Nothing has to
|
|
21
|
+
* remember what it meant to send.
|
|
22
|
+
* - **The only new state is when each user was last written to**, and it lives
|
|
23
|
+
* in `data/notification-digests.json` rather than in the database, because
|
|
24
|
+
* decision-9 says the database may be deleted whenever the site is stopped —
|
|
25
|
+
* and a forgotten timestamp would mean either a window silently skipped or a
|
|
26
|
+
* digest sent twice. It is its own file rather than a field in
|
|
27
|
+
* `data/users.json` because that file is the answer to "who may sign in",
|
|
28
|
+
* and a timestamp the sender rewrites every hour is bookkeeping rather than
|
|
29
|
+
* anything about the person.
|
|
30
|
+
* - **Nothing is sent for an empty queue, and an empty run records nothing.**
|
|
31
|
+
* A user with nothing waiting is never emailed, and because their timestamp
|
|
32
|
+
* does not move, the first thing that does arrive goes out on the very next
|
|
33
|
+
* tick rather than waiting out a window that had nothing in it. The promise
|
|
34
|
+
* a mode makes is "at most one message per window", and that is kept.
|
|
35
|
+
*/
|
|
36
|
+
/** The message a batched user gets: everything still waiting, in one. */
|
|
37
|
+
export declare const COMMENT_DIGEST_TEMPLATE = "comment-digest";
|
|
38
|
+
/** The file, relative to `dataDir`. */
|
|
39
|
+
export declare const DIGEST_TIMES_FILE = "notification-digests.json";
|
|
40
|
+
/** Nobody but the site's own user reads it. */
|
|
41
|
+
export declare const DIGEST_TIMES_FILE_MODE = 384;
|
|
42
|
+
/**
|
|
43
|
+
* How often the timer looks.
|
|
44
|
+
*
|
|
45
|
+
* A minute. The tick is not the window — each user's own mode decides whether
|
|
46
|
+
* they are due — so this only sets how promptly a window that has come up is
|
|
47
|
+
* noticed, and a minute's lag on an hourly digest is nothing while a busier
|
|
48
|
+
* tick would be a query a minute for no one.
|
|
49
|
+
*/
|
|
50
|
+
export declare const DIGEST_TICK_MS: number;
|
|
51
|
+
/**
|
|
52
|
+
* The most items one digest lists.
|
|
53
|
+
*
|
|
54
|
+
* A cap rather than "everything", because "everything" during a spam wave is a
|
|
55
|
+
* message with thousands of entries and three signed links each, which no mail
|
|
56
|
+
* provider would take and nobody could read. What is over the cap is counted
|
|
57
|
+
* in a line at the bottom pointing at the moderation queue, and the next
|
|
58
|
+
* window lists the next hundred.
|
|
59
|
+
*/
|
|
60
|
+
export declare const DIGEST_MAX_ITEMS = 100;
|
|
61
|
+
/** Where the digest times live for a given data directory. */
|
|
62
|
+
export declare function digestTimesFile(dataDir: string): string;
|
|
63
|
+
/**
|
|
64
|
+
* When each user last had a digest of each event, as
|
|
65
|
+
* `{ [event]: { [userId]: instant } }`.
|
|
66
|
+
*
|
|
67
|
+
* Keyed by event as well as by user because the registry may grow a second
|
|
68
|
+
* batched notice, and the two would then be on windows of their own. A file
|
|
69
|
+
* that is missing, damaged or the wrong shape reads as nobody having had
|
|
70
|
+
* anything — the same direction {@link readCommentOptOuts} fails in, and for
|
|
71
|
+
* the same reason: the cost is a duplicate digest, and the alternative is a
|
|
72
|
+
* site whose timer throws over a stray comma.
|
|
73
|
+
*/
|
|
74
|
+
export declare function readDigestTimes(dataDir: string): Record<string, Record<string, string>>;
|
|
75
|
+
/**
|
|
76
|
+
* Write down that these users have just been sent a digest of this event.
|
|
77
|
+
*
|
|
78
|
+
* The read is inside the write, so two runs at once cannot lose one another's
|
|
79
|
+
* timestamps.
|
|
80
|
+
*/
|
|
81
|
+
export declare function recordDigestTimes(dataDir: string, event: string, users: readonly number[], at: Date): Promise<void>;
|
|
82
|
+
/**
|
|
83
|
+
* The timer the digest waits on, injected so a test can fire it rather than
|
|
84
|
+
* wait for it. The shape {@link ScheduleTimers} has, for the same reason: a
|
|
85
|
+
* repeating tick, unreferenced so it never holds the process open on its own.
|
|
86
|
+
*/
|
|
87
|
+
export interface NotificationTimers {
|
|
88
|
+
set(callback: () => void, everyMs: number): unknown;
|
|
89
|
+
clear(handle: unknown): void;
|
|
90
|
+
}
|
|
91
|
+
/** The real one. */
|
|
92
|
+
export declare const systemNotificationTimers: NotificationTimers;
|
|
93
|
+
/** Where a digest run reports what it could not do. `console` will do. */
|
|
94
|
+
export interface DigestLogger {
|
|
95
|
+
warn(message: string): void;
|
|
96
|
+
}
|
|
97
|
+
/** What {@link createCommentDigest} needs. */
|
|
98
|
+
export interface CreateCommentDigestOptions {
|
|
99
|
+
/** The comment index, which is what "still pending" is asked of. */
|
|
100
|
+
admin: AdminStore;
|
|
101
|
+
/** The content index, for the posts the items are on. */
|
|
102
|
+
store: ContentStore;
|
|
103
|
+
/** The one door out for email. */
|
|
104
|
+
mail: MailService;
|
|
105
|
+
/**
|
|
106
|
+
* Config after defaults: the base URL the links are absolute against, the
|
|
107
|
+
* data directory the signing secret and the record live in, and the clock.
|
|
108
|
+
*/
|
|
109
|
+
config: Pick<ResolvedConfig, 'baseUrl' | 'dataDir' | 'now'>;
|
|
110
|
+
/** The timer to tick on. Defaults to {@link systemNotificationTimers}. */
|
|
111
|
+
timers?: NotificationTimers | undefined;
|
|
112
|
+
/** How often it ticks. Defaults to {@link DIGEST_TICK_MS}. */
|
|
113
|
+
tickMs?: number | undefined;
|
|
114
|
+
/** The most items one message lists. Defaults to {@link DIGEST_MAX_ITEMS}. */
|
|
115
|
+
maxItems?: number | undefined;
|
|
116
|
+
/** Where failures are reported. Defaults to `console`. */
|
|
117
|
+
logger?: DigestLogger | undefined;
|
|
118
|
+
}
|
|
119
|
+
/** Sends the batched notices. Never throws, and never waits on a provider. */
|
|
120
|
+
export interface CommentDigest {
|
|
121
|
+
/**
|
|
122
|
+
* Send a digest to every user who is due one and has something waiting.
|
|
123
|
+
* Resolves with how many messages were handed to the mail service.
|
|
124
|
+
*/
|
|
125
|
+
run(): Promise<number>;
|
|
126
|
+
/** Start ticking. Safe twice. */
|
|
127
|
+
start(): void;
|
|
128
|
+
/** Stop ticking. Safe before starting and safe twice. */
|
|
129
|
+
stop(): void;
|
|
130
|
+
/** Resolve once the run in flight, if there is one, has finished. */
|
|
131
|
+
settled(): Promise<void>;
|
|
132
|
+
}
|
|
133
|
+
/** Build the digest sender for one site. */
|
|
134
|
+
export declare function createCommentDigest(options: CreateCommentDigestOptions): CommentDigest;
|
|
135
|
+
//# sourceMappingURL=digest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"digest.d.ts","sourceRoot":"","sources":["../../src/notifications/digest.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAe,MAAM,mBAAmB,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAUtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,yEAAyE;AACzE,eAAO,MAAM,uBAAuB,mBAAmB,CAAC;AAExD,uCAAuC;AACvC,eAAO,MAAM,iBAAiB,8BAA8B,CAAC;AAE7D,+CAA+C;AAC/C,eAAO,MAAM,sBAAsB,MAAQ,CAAC;AAE5C;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,QAAY,CAAC;AAExC;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,MAAM,CAAC;AAEpC,8DAA8D;AAC9D,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAEvF;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,EAAE,EAAE,IAAI,GACP,OAAO,CAAC,IAAI,CAAC,CAaf;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,GAAG,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IACpD,KAAK,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;CAC9B;AAED,oBAAoB;AACpB,eAAO,MAAM,wBAAwB,EAAE,kBAStC,CAAC;AAEF,0EAA0E;AAC1E,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,8CAA8C;AAC9C,MAAM,WAAW,0BAA0B;IACzC,oEAAoE;IACpE,KAAK,EAAE,UAAU,CAAC;IAClB,yDAAyD;IACzD,KAAK,EAAE,YAAY,CAAC;IACpB,kCAAkC;IAClC,IAAI,EAAE,WAAW,CAAC;IAClB;;;OAGG;IACH,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,SAAS,GAAG,SAAS,GAAG,KAAK,CAAC,CAAC;IAC5D,0EAA0E;IAC1E,MAAM,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAC;IACxC,8DAA8D;IAC9D,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,0DAA0D;IAC1D,MAAM,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;CACnC;AAED,8EAA8E;AAC9E,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IACvB,iCAAiC;IACjC,KAAK,IAAI,IAAI,CAAC;IACd,yDAAyD;IACzD,IAAI,IAAI,IAAI,CAAC;IACb,qEAAqE;IACrE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED,4CAA4C;AAC5C,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,0BAA0B,GAAG,aAAa,CA0ItF"}
|