@geekity/cms 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2217 -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/{layouts/document-editor.njk → pages/documents/editor.njk} +75 -59
- 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/federation/settings.njk +77 -0
- package/admin/pages/media/library.njk +160 -0
- package/admin/pages/messages/all.njk +110 -0
- package/admin/pages/navigation/menus.njk +129 -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/general.njk +29 -0
- package/admin/pages/settings/permalinks.njk +50 -0
- package/admin/pages/settings/reading.njk +64 -0
- package/admin/pages/tools/content-index.njk +89 -0
- package/admin/pages/users/edit.njk +239 -0
- package/admin/pages/users/list.njk +51 -0
- package/admin/pages/users/new.njk +41 -0
- package/admin/static/admin.css +558 -3
- package/admin/static/copy.js +52 -0
- package/admin/static/editor.js +16 -16
- package/admin/static/slug.js +61 -0
- package/dist/access-log.d.ts +44 -0
- package/dist/access-log.d.ts.map +1 -0
- package/dist/access-log.js +71 -0
- package/dist/access-log.js.map +1 -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 +117 -10
- package/dist/admin/documents.d.ts.map +1 -1
- package/dist/admin/documents.js +328 -41
- package/dist/admin/documents.js.map +1 -1
- package/dist/admin/federation.d.ts +161 -50
- package/dist/admin/federation.d.ts.map +1 -1
- package/dist/admin/federation.js +235 -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 +143 -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/navigation.d.ts +155 -0
- package/dist/admin/navigation.d.ts.map +1 -0
- package/dist/admin/navigation.js +292 -0
- package/dist/admin/navigation.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 +164 -105
- package/dist/admin/routes.js.map +1 -1
- package/dist/admin/session.d.ts +17 -3
- package/dist/admin/session.d.ts.map +1 -1
- package/dist/admin/session.js +19 -5
- package/dist/admin/session.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 +48 -0
- package/dist/admin/settings-federation.d.ts.map +1 -0
- package/dist/admin/settings-federation.js +123 -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 +119 -0
- package/dist/admin/settings-page.d.ts.map +1 -0
- package/dist/admin/settings-page.js +132 -0
- package/dist/admin/settings-page.js.map +1 -0
- package/dist/admin/settings-pages.d.ts +30 -0
- package/dist/admin/settings-pages.d.ts.map +1 -0
- package/dist/admin/settings-pages.js +43 -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 +34 -0
- package/dist/admin/settings-reading.d.ts.map +1 -0
- package/dist/admin/settings-reading.js +49 -0
- package/dist/admin/settings-reading.js.map +1 -0
- package/dist/admin/settings.d.ts +339 -96
- package/dist/admin/settings.d.ts.map +1 -1
- package/dist/admin/settings.js +600 -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 +46 -14
- package/dist/admin/templates.d.ts.map +1 -1
- package/dist/admin/templates.js +46 -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/tools.d.ts +111 -0
- package/dist/admin/tools.d.ts.map +1 -0
- package/dist/admin/tools.js +182 -0
- package/dist/admin/tools.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 +429 -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 +123 -0
- package/dist/comments/form.d.ts.map +1 -0
- package/dist/comments/form.js +79 -0
- package/dist/comments/form.js.map +1 -0
- package/dist/comments/index.d.ts +16 -0
- package/dist/comments/index.d.ts.map +1 -0
- package/dist/comments/index.js +10 -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 +60 -0
- package/dist/comments/routes.d.ts.map +1 -0
- package/dist/comments/routes.js +212 -0
- package/dist/comments/routes.js.map +1 -0
- package/dist/comments/submission.d.ts +297 -0
- package/dist/comments/submission.d.ts.map +1 -0
- package/dist/comments/submission.js +280 -0
- package/dist/comments/submission.js.map +1 -0
- package/dist/comments/viewer.d.ts +21 -0
- package/dist/comments/viewer.d.ts.map +1 -0
- package/dist/comments/viewer.js +45 -0
- package/dist/comments/viewer.js.map +1 -0
- package/dist/config.d.ts +225 -5
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +121 -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 +220 -7
- package/dist/content/store.d.ts.map +1 -1
- package/dist/content/store.js +392 -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 +70 -5
- 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 +46 -10
- package/dist/federation/mount.d.ts.map +1 -1
- package/dist/federation/mount.js +300 -28
- 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 +344 -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 +195 -0
- package/dist/web/navigation.d.ts.map +1 -0
- package/dist/web/navigation.js +300 -0
- package/dist/web/navigation.js.map +1 -0
- package/dist/web/negotiate.d.ts +31 -0
- package/dist/web/negotiate.d.ts.map +1 -1
- package/dist/web/negotiate.js +31 -11
- 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 +203 -9
- package/dist/web/render.d.ts.map +1 -1
- package/dist/web/render.js +341 -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 +854 -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 +226 -0
- package/dist/web/themes.d.ts.map +1 -0
- package/dist/web/themes.js +314 -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 +8 -0
- package/templates/site/content/pages/about.md +7 -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 +1216 -50
- package/themes/default/layouts/404.njk +2 -3
- package/themes/default/layouts/author.njk +36 -0
- package/themes/default/layouts/base.njk +161 -31
- package/themes/default/layouts/category.njk +27 -0
- package/themes/default/layouts/front-page.njk +56 -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 +71 -0
- package/themes/default/partials/comment-form.njk +137 -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/menu.njk +32 -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 +22 -0
- package/themes/default/partials/tags.njk +26 -5
- package/themes/default/static/highlight.js +4 -0
- package/themes/default/static/style.css +1142 -194
- package/themes/default/theme.json +9 -0
- 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,79 @@
|
|
|
1
|
+
import { COMMENT_FIELDS, MAXIMUM_BODY_LENGTH, MAXIMUM_NAME_LENGTH } from './submission.js';
|
|
2
|
+
/**
|
|
3
|
+
* The same form drawn for somebody the site knows rather than for a stranger.
|
|
4
|
+
*
|
|
5
|
+
* A function over a built form rather than another parameter on the two
|
|
6
|
+
* builders, so `commentForm` and `refilledCommentForm` keep the signatures the
|
|
7
|
+
* package publishes and there is one place that decides what "signed in"
|
|
8
|
+
* changes about a form.
|
|
9
|
+
*/
|
|
10
|
+
export function signedInCommentForm(form, viewer) {
|
|
11
|
+
return {
|
|
12
|
+
...form,
|
|
13
|
+
signedInAs: { name: viewer.name, url: viewer.url },
|
|
14
|
+
csrfToken: viewer.csrfToken,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/** Where the comment form posts. */
|
|
18
|
+
export const COMMENT_POST_PATH = '/_geekity/comments';
|
|
19
|
+
/** The query the redirect after a submission carries, and what it can say. */
|
|
20
|
+
export const COMMENT_NOTICE_PARAM = 'comment';
|
|
21
|
+
/**
|
|
22
|
+
* The query a Reply link on a comment carries.
|
|
23
|
+
*
|
|
24
|
+
* Threading without a line of JavaScript: the link goes to the form with the
|
|
25
|
+
* comment it answers named in the URL, the form puts that in its hidden field,
|
|
26
|
+
* and Cancel is a link back to the page without the query.
|
|
27
|
+
*/
|
|
28
|
+
export const COMMENT_REPLY_PARAM = 'reply_to';
|
|
29
|
+
/**
|
|
30
|
+
* What that query means, and what the reader is told.
|
|
31
|
+
*
|
|
32
|
+
* A redirect rather than a rendered page, so a refresh does not post the
|
|
33
|
+
* comment again; a query rather than a flash, because a reader has no session
|
|
34
|
+
* to hang one on.
|
|
35
|
+
*/
|
|
36
|
+
export const COMMENT_NOTICES = {
|
|
37
|
+
posted: 'Thank you — your comment is on the page.',
|
|
38
|
+
pending: 'Thank you — your comment is waiting to be approved.',
|
|
39
|
+
};
|
|
40
|
+
/** A fresh, empty form for a post that is taking comments. */
|
|
41
|
+
export function commentForm(document, now = new Date(), notifiable = false) {
|
|
42
|
+
return refilledCommentForm(document, blankValues(), {}, now, undefined, notifiable);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* The same form with what somebody typed still in it.
|
|
46
|
+
*
|
|
47
|
+
* What a refused submission is answered with: losing a paragraph because an
|
|
48
|
+
* email address had a typo in it is the fastest way to lose a commenter.
|
|
49
|
+
*/
|
|
50
|
+
export function refilledCommentForm(document, values, problems, now = new Date(), error, notifiable = false) {
|
|
51
|
+
return {
|
|
52
|
+
action: COMMENT_POST_PATH,
|
|
53
|
+
fields: COMMENT_FIELDS,
|
|
54
|
+
post: document.slug,
|
|
55
|
+
loaded: String(now.getTime()),
|
|
56
|
+
values,
|
|
57
|
+
problems,
|
|
58
|
+
notifiable,
|
|
59
|
+
nameLength: MAXIMUM_NAME_LENGTH,
|
|
60
|
+
bodyLength: MAXIMUM_BODY_LENGTH,
|
|
61
|
+
...(error === undefined ? {} : { error }),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/** What a form holds before anybody has typed in it. */
|
|
65
|
+
export function blankValues() {
|
|
66
|
+
return { name: '', email: '', url: '', body: '', inReplyTo: '', notify: '' };
|
|
67
|
+
}
|
|
68
|
+
/** What a submitted form typed, for putting back in a refused one. */
|
|
69
|
+
export function valuesOf(form) {
|
|
70
|
+
return {
|
|
71
|
+
name: form.name,
|
|
72
|
+
email: form.email,
|
|
73
|
+
url: form.url,
|
|
74
|
+
body: form.body,
|
|
75
|
+
inReplyTo: form.inReplyTo,
|
|
76
|
+
notify: form.notify,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=form.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form.js","sourceRoot":"","sources":["../../src/comments/form.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AA+E3F;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CACjC,IAAwB,EACxB,MAAqB;IAErB,OAAO;QACL,GAAG,IAAI;QACP,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE;QAClD,SAAS,EAAE,MAAM,CAAC,SAAS;KAC5B,CAAC;AACJ,CAAC;AAED,oCAAoC;AACpC,MAAM,CAAC,MAAM,iBAAiB,GAAG,oBAAoB,CAAC;AAEtD,8EAA8E;AAC9E,MAAM,CAAC,MAAM,oBAAoB,GAAG,SAAS,CAAC;AAE9C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,UAAU,CAAC;AAE9C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAAqC;IAC/D,MAAM,EAAE,0CAA0C;IAClD,OAAO,EAAE,qDAAqD;CAC/D,CAAC;AAEF,8DAA8D;AAC9D,MAAM,UAAU,WAAW,CACzB,QAAkB,EAClB,GAAG,GAAS,IAAI,IAAI,EAAE,EACtB,UAAU,GAAG,KAAK;IAElB,OAAO,mBAAmB,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AACtF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CACjC,QAAkB,EAClB,MAAoC,EACpC,QAAyB,EACzB,GAAG,GAAS,IAAI,IAAI,EAAE,EACtB,KAAc,EACd,UAAU,GAAG,KAAK;IAElB,OAAO;QACL,MAAM,EAAE,iBAAiB;QACzB,MAAM,EAAE,cAAc;QACtB,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QAC7B,MAAM;QACN,QAAQ;QACR,UAAU;QACV,UAAU,EAAE,mBAAmB;QAC/B,UAAU,EAAE,mBAAmB;QAC/B,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;KAC1C,CAAC;AACJ,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,WAAW;IACzB,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;AAC/E,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,QAAQ,CAAC,IAAiB;IACxC,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,MAAM,EAAE,IAAI,CAAC,MAAM;KACpB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export { AKISMET_ENDPOINT, AKISMET_KEY_FILE, AKISMET_TIMEOUT_MS, AKISMET_USER_AGENT, akismetKeyPath, createAkismetChecker, readAkismetKey, removeAkismetKey, verifyAkismetKey, writeAkismetKey, } from './akismet.ts';
|
|
2
|
+
export type { AkismetCheckerOptions, AkismetKeyRecord, AkismetKeyStatus, VerifyAkismetKeyOptions, } from './akismet.ts';
|
|
3
|
+
export { blankValues, COMMENT_NOTICE_PARAM, COMMENT_NOTICES, COMMENT_POST_PATH, COMMENT_REPLY_PARAM, commentForm, refilledCommentForm, signedInCommentForm, valuesOf, } from './form.ts';
|
|
4
|
+
export type { CommentFormContext, CommentViewer } from './form.ts';
|
|
5
|
+
export { renderCommentMarkdown } from './markdown.ts';
|
|
6
|
+
export { isModerationAction, moderateComment, MODERATION_ACTIONS } from './moderate.ts';
|
|
7
|
+
export type { ModerateCommentOptions, ModerationAction, ModerationOutcome } from './moderate.ts';
|
|
8
|
+
export { COMMENTS_FRONT_MATTER_KEY, commentPolicyOf, commentsOpen, DEFAULT_COMMENTS_CLOSE_AFTER_DAYS, } from './policy.ts';
|
|
9
|
+
export type { CommentPolicy } from './policy.ts';
|
|
10
|
+
export { addComment, COMMENTS_DATA_DIRECTORY, commentsDirectory, commentsFile, deleteComment, heldWebmention, intakeComment, readComments, rebuildCommentIndexes, updateComment, } from './records.ts';
|
|
11
|
+
export type { CommentIndexReport, CommentIntakeOutcome, CommentNotices, CommentOrigin, CommentRecords, IntakeCommentOptions, NewComment, ProposedComment, } from './records.ts';
|
|
12
|
+
export { commentFormFor, commentNoticeFor, mountComments } from './routes.ts';
|
|
13
|
+
export { COMMENT_FIELDS, COMMENT_RATE_LIMIT, COMMENT_RATE_WINDOW_SECONDS, COMMENT_SALT_FILE, commentKeys, commentProblems, hashClientAddress, MAXIMUM_BODY_LENGTH, MAXIMUM_NAME_LENGTH, MAXIMUM_URL_LENGTH, MAXIMUM_FORM_AGE_SECONDS, MINIMUM_SUBMIT_SECONDS, normalizeWebsite, submitComment, } from './submission.ts';
|
|
14
|
+
export type { CommentChecker, CommentForm, CommentOutcome, CommentProblems, CommentRefusal, CommentReport, CommentSubmission, SubmissionType, CommentThrottle, CommentVerdict, SignedInAuthor, SubmitCommentOptions, } from './submission.ts';
|
|
15
|
+
export { signedInCommenter } from './viewer.ts';
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/comments/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,oBAAoB,EACpB,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,GAChB,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,qBAAqB,EACrB,gBAAgB,EAChB,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,WAAW,EACX,mBAAmB,EACnB,mBAAmB,EACnB,QAAQ,GACT,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AACnE,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACxF,YAAY,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACjG,OAAO,EACL,yBAAyB,EACzB,eAAe,EACf,YAAY,EACZ,iCAAiC,GAClC,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EACL,UAAU,EACV,uBAAuB,EACvB,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,cAAc,EACd,aAAa,EACb,YAAY,EACZ,qBAAqB,EACrB,aAAa,GACd,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,EACd,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,UAAU,EACV,eAAe,GAChB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,2BAA2B,EAC3B,iBAAiB,EACjB,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,wBAAwB,EACxB,sBAAsB,EACtB,gBAAgB,EAChB,aAAa,GACd,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,cAAc,EACd,WAAW,EACX,cAAc,EACd,eAAe,EACf,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,cAAc,EACd,cAAc,EACd,oBAAoB,GACrB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { AKISMET_ENDPOINT, AKISMET_KEY_FILE, AKISMET_TIMEOUT_MS, AKISMET_USER_AGENT, akismetKeyPath, createAkismetChecker, readAkismetKey, removeAkismetKey, verifyAkismetKey, writeAkismetKey, } from './akismet.js';
|
|
2
|
+
export { blankValues, COMMENT_NOTICE_PARAM, COMMENT_NOTICES, COMMENT_POST_PATH, COMMENT_REPLY_PARAM, commentForm, refilledCommentForm, signedInCommentForm, valuesOf, } from './form.js';
|
|
3
|
+
export { renderCommentMarkdown } from './markdown.js';
|
|
4
|
+
export { isModerationAction, moderateComment, MODERATION_ACTIONS } from './moderate.js';
|
|
5
|
+
export { COMMENTS_FRONT_MATTER_KEY, commentPolicyOf, commentsOpen, DEFAULT_COMMENTS_CLOSE_AFTER_DAYS, } from './policy.js';
|
|
6
|
+
export { addComment, COMMENTS_DATA_DIRECTORY, commentsDirectory, commentsFile, deleteComment, heldWebmention, intakeComment, readComments, rebuildCommentIndexes, updateComment, } from './records.js';
|
|
7
|
+
export { commentFormFor, commentNoticeFor, mountComments } from './routes.js';
|
|
8
|
+
export { COMMENT_FIELDS, COMMENT_RATE_LIMIT, COMMENT_RATE_WINDOW_SECONDS, COMMENT_SALT_FILE, commentKeys, commentProblems, hashClientAddress, MAXIMUM_BODY_LENGTH, MAXIMUM_NAME_LENGTH, MAXIMUM_URL_LENGTH, MAXIMUM_FORM_AGE_SECONDS, MINIMUM_SUBMIT_SECONDS, normalizeWebsite, submitComment, } from './submission.js';
|
|
9
|
+
export { signedInCommenter } from './viewer.js';
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/comments/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,oBAAoB,EACpB,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,GAChB,MAAM,cAAc,CAAC;AAOtB,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,WAAW,EACX,mBAAmB,EACnB,mBAAmB,EACnB,QAAQ,GACT,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAExF,OAAO,EACL,yBAAyB,EACzB,eAAe,EACf,YAAY,EACZ,iCAAiC,GAClC,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,UAAU,EACV,uBAAuB,EACvB,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,cAAc,EACd,aAAa,EACb,YAAY,EACZ,qBAAqB,EACrB,aAAa,GACd,MAAM,cAAc,CAAC;AAWtB,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,2BAA2B,EAC3B,iBAAiB,EACjB,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,wBAAwB,EACxB,sBAAsB,EACtB,gBAAgB,EAChB,aAAa,GACd,MAAM,iBAAiB,CAAC;AAezB,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A comment body as the HTML the page and the feeds carry.
|
|
3
|
+
*
|
|
4
|
+
* An empty body is empty HTML rather than a stray newline, so nothing calling
|
|
5
|
+
* this has to decide whether "nothing" is worth printing.
|
|
6
|
+
*/
|
|
7
|
+
export declare function renderCommentMarkdown(body: string): string;
|
|
8
|
+
//# sourceMappingURL=markdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/comments/markdown.ts"],"names":[],"mappings":"AA2EA;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG1D"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import MarkdownIt from 'markdown-it';
|
|
2
|
+
/**
|
|
3
|
+
* The Markdown a stranger is allowed to write.
|
|
4
|
+
*
|
|
5
|
+
* A post is written by somebody who has signed in, so `content/markdown.ts`
|
|
6
|
+
* renders it with Eleventy's own options — raw HTML included. A comment is
|
|
7
|
+
* written by anybody at all, so it gets its own renderer rather than a
|
|
8
|
+
* sanitising pass over the same one: what is not produced cannot leak, and a
|
|
9
|
+
* profile is easier to read than a list of what was taken out again.
|
|
10
|
+
*
|
|
11
|
+
* Three things are different from the site's own renderer:
|
|
12
|
+
*
|
|
13
|
+
* - **No raw HTML.** `html: false` escapes it, so a `<script>` a commenter
|
|
14
|
+
* typed is the word they typed.
|
|
15
|
+
* - **Every link marked.** `rel="nofollow ugc"` on links written and on bare
|
|
16
|
+
* URLs alike: a comment is user-generated content pointing somewhere else,
|
|
17
|
+
* which is exactly what the two tokens are for.
|
|
18
|
+
* - **No embedding.** An image becomes a link to it. Rendering `<img>` would
|
|
19
|
+
* let a commenter put a stranger's file — and a tracking pixel that logs
|
|
20
|
+
* every reader's address — on somebody else's page.
|
|
21
|
+
*
|
|
22
|
+
* Links are also held to an allowlist of schemes, so nothing reaches a reader
|
|
23
|
+
* that a browser would treat as a program. That is the same list
|
|
24
|
+
* `web/sanitize.ts` publishes remote HTML through, spelled again here because
|
|
25
|
+
* this renderer never sees that module's output.
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* URL schemes a link in a comment may use.
|
|
29
|
+
*
|
|
30
|
+
* An allowlist rather than a `javascript:` denylist: `data:` and `vbscript:`
|
|
31
|
+
* are as dangerous, and the next scheme somebody thinks of is on no list
|
|
32
|
+
* written today.
|
|
33
|
+
*/
|
|
34
|
+
const ALLOWED_SCHEMES = ['http://', 'https://', 'mailto:'];
|
|
35
|
+
/** What every link a comment carries is marked with. */
|
|
36
|
+
const LINK_REL = 'nofollow ugc';
|
|
37
|
+
const markdown = new MarkdownIt({
|
|
38
|
+
html: false,
|
|
39
|
+
linkify: true,
|
|
40
|
+
breaks: true,
|
|
41
|
+
});
|
|
42
|
+
markdown.validateLink = (url) => {
|
|
43
|
+
const lowered = url.trim().toLowerCase();
|
|
44
|
+
return ALLOWED_SCHEMES.some((scheme) => lowered.startsWith(scheme));
|
|
45
|
+
};
|
|
46
|
+
// Every link, however it was written: `[words](url)`, a bare URL linkify
|
|
47
|
+
// found, or a reference definition. One rule covers all three, because
|
|
48
|
+
// markdown-it emits the same token for each.
|
|
49
|
+
markdown.renderer.rules['link_open'] = (tokens, index, options, _env, self) => {
|
|
50
|
+
const token = tokens[index];
|
|
51
|
+
token?.attrSet('rel', LINK_REL);
|
|
52
|
+
return self.renderToken(tokens, index, options);
|
|
53
|
+
};
|
|
54
|
+
// An image, as the link it points at. The alt text is what the commenter meant
|
|
55
|
+
// to say about it, so that is what the link reads; an image with no alt is
|
|
56
|
+
// linked by its URL, which is better than an empty anchor.
|
|
57
|
+
markdown.renderer.rules['image'] = (tokens, index, options, env, self) => {
|
|
58
|
+
const token = tokens[index];
|
|
59
|
+
const alt = self.renderInlineAsText(token?.children ?? [], options, env);
|
|
60
|
+
const href = String(token?.attrGet('src') ?? '');
|
|
61
|
+
// A source this site would not publish as a link is not published as one
|
|
62
|
+
// here either; the words the commenter wrote about it stay.
|
|
63
|
+
if (!markdown.validateLink(href))
|
|
64
|
+
return escapeText(alt);
|
|
65
|
+
return `<a href="${escapeAttribute(href)}" rel="${LINK_REL}">${escapeText(alt || href)}</a>`;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* A comment body as the HTML the page and the feeds carry.
|
|
69
|
+
*
|
|
70
|
+
* An empty body is empty HTML rather than a stray newline, so nothing calling
|
|
71
|
+
* this has to decide whether "nothing" is worth printing.
|
|
72
|
+
*/
|
|
73
|
+
export function renderCommentMarkdown(body) {
|
|
74
|
+
const trimmed = body.trim();
|
|
75
|
+
return trimmed === '' ? '' : markdown.render(trimmed);
|
|
76
|
+
}
|
|
77
|
+
/** A URL as an attribute value. */
|
|
78
|
+
function escapeAttribute(value) {
|
|
79
|
+
return escapeText(value).replaceAll('"', '"');
|
|
80
|
+
}
|
|
81
|
+
/** Text as markup. */
|
|
82
|
+
function escapeText(value) {
|
|
83
|
+
return value.replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>');
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/comments/markdown.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,aAAa,CAAC;AAGrC;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH;;;;;;GAMG;AACH,MAAM,eAAe,GAAsB,CAAC,SAAS,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;AAE9E,wDAAwD;AACxD,MAAM,QAAQ,GAAG,cAAc,CAAC;AAEhC,MAAM,QAAQ,GAAuB,IAAI,UAAU,CAAC;IAClD,IAAI,EAAE,KAAK;IACX,OAAO,EAAE,IAAI;IACb,MAAM,EAAE,IAAI;CACb,CAAC,CAAC;AAEH,QAAQ,CAAC,YAAY,GAAG,CAAC,GAAG,EAAE,EAAE;IAC9B,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACzC,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;AACtE,CAAC,CAAC;AAEF,yEAAyE;AACzE,uEAAuE;AACvE,6CAA6C;AAC7C,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;IAC5E,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5B,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAChC,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;AAClD,CAAC,CAAC;AAEF,+EAA+E;AAC/E,2EAA2E;AAC3E,2DAA2D;AAC3D,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;IACvE,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,QAAQ,IAAI,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;IACzE,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IACjD,yEAAyE;IACzE,4DAA4D;IAC5D,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC;QAAE,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC;IAEzD,OAAO,YAAY,eAAe,CAAC,IAAI,CAAC,UAAU,QAAQ,KAAK,UAAU,CAAC,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC;AAC/F,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,OAAO,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AACxD,CAAC;AAED,mCAAmC;AACnC,SAAS,eAAe,CAAC,KAAa;IACpC,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;AACrD,CAAC;AAED,sBAAsB;AACtB,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;AACxF,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { CommentStatus, PostComment } from '../admin/store.ts';
|
|
2
|
+
import type { CommentRecords } from './records.ts';
|
|
3
|
+
import type { CommentChecker } from './submission.ts';
|
|
4
|
+
/**
|
|
5
|
+
* The three things that can be done to a stored comment, in one place.
|
|
6
|
+
*
|
|
7
|
+
* There are two doors onto them — the moderation screen, and the one-click
|
|
8
|
+
* links a notification carries (TASK-55) — and they have to agree about
|
|
9
|
+
* everything: which file is rewritten, when the index moves, and when a spam
|
|
10
|
+
* checker is told a human disagreed with it. Two copies of that would drift,
|
|
11
|
+
* and the way they would drift is that the email links would quietly stop
|
|
12
|
+
* training Akismet.
|
|
13
|
+
*
|
|
14
|
+
* So this is the whole of moderation, and both doors are a thin skin over it:
|
|
15
|
+
* one turns the outcome into a flash and a redirect, the other into a page a
|
|
16
|
+
* mail reader can show.
|
|
17
|
+
*/
|
|
18
|
+
/** What a button, or a link in a message, can do to a comment. */
|
|
19
|
+
export declare const MODERATION_ACTIONS: readonly ['approve', 'spam', 'delete'];
|
|
20
|
+
/** One of {@link MODERATION_ACTIONS}. */
|
|
21
|
+
export type ModerationAction = (typeof MODERATION_ACTIONS)[number];
|
|
22
|
+
/** Whether a name is one of them. */
|
|
23
|
+
export declare function isModerationAction(value: string): value is ModerationAction;
|
|
24
|
+
/** What became of one moderation. */
|
|
25
|
+
export type ModerationOutcome =
|
|
26
|
+
/** There is no such comment; somebody else has already dealt with it. */
|
|
27
|
+
{
|
|
28
|
+
readonly kind: 'gone';
|
|
29
|
+
}
|
|
30
|
+
/** It was already exactly that, so nothing was written. */
|
|
31
|
+
| {
|
|
32
|
+
readonly kind: 'unchanged';
|
|
33
|
+
readonly comment: PostComment;
|
|
34
|
+
}
|
|
35
|
+
/** It moved, and this is where it was before. */
|
|
36
|
+
| {
|
|
37
|
+
readonly kind: 'moved';
|
|
38
|
+
readonly comment: PostComment;
|
|
39
|
+
readonly before: CommentStatus;
|
|
40
|
+
}
|
|
41
|
+
/** It is gone now. The comment is what it was when it went. */
|
|
42
|
+
| {
|
|
43
|
+
readonly kind: 'deleted';
|
|
44
|
+
readonly comment: PostComment;
|
|
45
|
+
};
|
|
46
|
+
/** What {@link moderateComment} needs around it. */
|
|
47
|
+
export interface ModerateCommentOptions {
|
|
48
|
+
/** The files and the index every action writes through. */
|
|
49
|
+
records: CommentRecords;
|
|
50
|
+
/** Which comment. */
|
|
51
|
+
id: string;
|
|
52
|
+
/** What to do to it. */
|
|
53
|
+
action: ModerationAction;
|
|
54
|
+
/** The checker, when the site named one, so a change of mind can be reported. */
|
|
55
|
+
checker?: CommentChecker | undefined;
|
|
56
|
+
/** The site's public origin, which a report names the post by. */
|
|
57
|
+
baseUrl: string;
|
|
58
|
+
/** Where a checker that will not take a correction is reported. */
|
|
59
|
+
logger?: {
|
|
60
|
+
warn(message: string): void;
|
|
61
|
+
} | undefined;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Approve a comment, file it as spam, or forget it.
|
|
65
|
+
*
|
|
66
|
+
* The file is rewritten first and the index inside the same step, exactly as
|
|
67
|
+
* the form on the public site does it: the file is the comment (decision-9),
|
|
68
|
+
* and moderation only ever moves it.
|
|
69
|
+
*/
|
|
70
|
+
export declare function moderateComment(options: ModerateCommentOptions): Promise<ModerationOutcome>;
|
|
71
|
+
//# sourceMappingURL=moderate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"moderate.d.ts","sourceRoot":"","sources":["../../src/comments/moderate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAiB,MAAM,iBAAiB,CAAC;AAErE;;;;;;;;;;;;;GAaG;AAEH,kEAAkE;AAClE,eAAO,MAAM,kBAAkB,YAAI,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAU,CAAC;AAEzE,yCAAyC;AACzC,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnE,qCAAqC;AACrC,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,gBAAgB,CAE3E;AAED,qCAAqC;AACrC,MAAM,MAAM,iBAAiB;AAC3B,yEAAyE;AACvE;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AAC3B,2DAA2D;GACzD;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;CAAE;AAC/D,iDAAiD;GAC/C;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;CAAE;AAC3F,+DAA+D;GAC7D;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;CAAE,CAAC;AAEhE,oDAAoD;AACpD,MAAM,WAAW,sBAAsB;IACrC,2DAA2D;IAC3D,OAAO,EAAE,cAAc,CAAC;IACxB,qBAAqB;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,wBAAwB;IACxB,MAAM,EAAE,gBAAgB,CAAC;IACzB,iFAAiF;IACjF,OAAO,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IACrC,kEAAkE;IAClE,OAAO,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,SAAS,CAAC;CACtD;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAkBjG"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { deleteComment, updateComment } from './records.js';
|
|
2
|
+
/**
|
|
3
|
+
* The three things that can be done to a stored comment, in one place.
|
|
4
|
+
*
|
|
5
|
+
* There are two doors onto them — the moderation screen, and the one-click
|
|
6
|
+
* links a notification carries (TASK-55) — and they have to agree about
|
|
7
|
+
* everything: which file is rewritten, when the index moves, and when a spam
|
|
8
|
+
* checker is told a human disagreed with it. Two copies of that would drift,
|
|
9
|
+
* and the way they would drift is that the email links would quietly stop
|
|
10
|
+
* training Akismet.
|
|
11
|
+
*
|
|
12
|
+
* So this is the whole of moderation, and both doors are a thin skin over it:
|
|
13
|
+
* one turns the outcome into a flash and a redirect, the other into a page a
|
|
14
|
+
* mail reader can show.
|
|
15
|
+
*/
|
|
16
|
+
/** What a button, or a link in a message, can do to a comment. */
|
|
17
|
+
export const MODERATION_ACTIONS = ['approve', 'spam', 'delete'];
|
|
18
|
+
/** Whether a name is one of them. */
|
|
19
|
+
export function isModerationAction(value) {
|
|
20
|
+
return MODERATION_ACTIONS.includes(value);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Approve a comment, file it as spam, or forget it.
|
|
24
|
+
*
|
|
25
|
+
* The file is rewritten first and the index inside the same step, exactly as
|
|
26
|
+
* the form on the public site does it: the file is the comment (decision-9),
|
|
27
|
+
* and moderation only ever moves it.
|
|
28
|
+
*/
|
|
29
|
+
export async function moderateComment(options) {
|
|
30
|
+
const { records, id, action } = options;
|
|
31
|
+
const held = records.admin.getComment(id);
|
|
32
|
+
if (held === undefined)
|
|
33
|
+
return { kind: 'gone' };
|
|
34
|
+
if (action === 'delete') {
|
|
35
|
+
await deleteComment(records, id);
|
|
36
|
+
return { kind: 'deleted', comment: held };
|
|
37
|
+
}
|
|
38
|
+
const status = action === 'approve' ? 'approved' : 'spam';
|
|
39
|
+
if (held.status === status)
|
|
40
|
+
return { kind: 'unchanged', comment: held };
|
|
41
|
+
const moved = await updateComment(records, id, { status });
|
|
42
|
+
if (moved === undefined)
|
|
43
|
+
return { kind: 'gone' };
|
|
44
|
+
await tellChecker(options, moved, held.status);
|
|
45
|
+
return { kind: 'moved', comment: moved, before: held.status };
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Tell the checker, when there is one, that a human disagreed with it.
|
|
49
|
+
*
|
|
50
|
+
* Only a real change of mind is reported. Approving something that was merely
|
|
51
|
+
* waiting says nothing a checker did not already assume, and a service charged
|
|
52
|
+
* per call should not be told it twice.
|
|
53
|
+
*/
|
|
54
|
+
async function tellChecker(options, comment, before) {
|
|
55
|
+
const checker = options.checker;
|
|
56
|
+
if (checker === undefined)
|
|
57
|
+
return;
|
|
58
|
+
const report = {
|
|
59
|
+
comment,
|
|
60
|
+
url: absolute(comment.permalink, options.baseUrl),
|
|
61
|
+
baseUrl: options.baseUrl,
|
|
62
|
+
};
|
|
63
|
+
try {
|
|
64
|
+
if (comment.status === 'spam')
|
|
65
|
+
await checker.reportSpam?.(report);
|
|
66
|
+
else if (before === 'spam')
|
|
67
|
+
await checker.reportHam?.(report);
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
// The comment has already moved; a checker that cannot be told is a worse
|
|
71
|
+
// spam filter tomorrow, not a failed moderation action today.
|
|
72
|
+
const logger = options.logger ?? console;
|
|
73
|
+
logger.warn(`The comment checker would not take the correction: ${messageOf(error)}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/** A site-root path as an absolute URL. */
|
|
77
|
+
function absolute(pathname, baseUrl) {
|
|
78
|
+
try {
|
|
79
|
+
return new URL(pathname, baseUrl).href;
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return pathname;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function messageOf(error) {
|
|
86
|
+
return error instanceof Error ? error.message : String(error);
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=moderate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"moderate.js","sourceRoot":"","sources":["../../src/comments/moderate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAI5D;;;;;;;;;;;;;GAaG;AAEH,kEAAkE;AAClE,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAU,CAAC;AAKzE,qCAAqC;AACrC,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,OAAQ,kBAAwC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACnE,CAAC;AA6BD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAA+B;IACnE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IACxC,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAC1C,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAEhD,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,MAAM,aAAa,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACjC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC5C,CAAC;IAED,MAAM,MAAM,GAAkB,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC;IACzE,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM;QAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAExE,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,OAAO,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAC3D,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAEjD,MAAM,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC/C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;AAChE,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,WAAW,CACxB,OAA+B,EAC/B,OAAoB,EACpB,MAAqB;IAErB,MAAM,OAAO,GAA+B,OAAO,CAAC,OAAO,CAAC;IAC5D,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO;IAElC,MAAM,MAAM,GAAkB;QAC5B,OAAO;QACP,GAAG,EAAE,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC;QACjD,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,CAAC;IAEF,IAAI,CAAC;QACH,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM;YAAE,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC,MAAM,CAAC,CAAC;aAC7D,IAAI,MAAM,KAAK,MAAM;YAAE,MAAM,OAAO,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,CAAC;IAChE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,0EAA0E;QAC1E,8DAA8D;QAC9D,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC;QACzC,MAAM,CAAC,IAAI,CAAC,sDAAsD,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACxF,CAAC;AACH,CAAC;AAED,2CAA2C;AAC3C,SAAS,QAAQ,CAAC,QAAgB,EAAE,OAAe;IACjD,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,KAAc;IAC/B,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { Document } from '../content/document.ts';
|
|
2
|
+
/**
|
|
3
|
+
* When a post is taking comments, and when it has stopped.
|
|
4
|
+
*
|
|
5
|
+
* WordPress spells this as three things that argue with each other — a site
|
|
6
|
+
* switch, an age, and a per-post override — and so does this. They are read in
|
|
7
|
+
* one place so the form under a post and the endpoint that refuses a
|
|
8
|
+
* submission can never disagree about whether a post is open, which is the
|
|
9
|
+
* only way a comment form can lie to somebody who has just typed a paragraph.
|
|
10
|
+
*/
|
|
11
|
+
/** The front-matter key a post opens or closes its own comments with. */
|
|
12
|
+
export declare const COMMENTS_FRONT_MATTER_KEY = "comments";
|
|
13
|
+
/**
|
|
14
|
+
* How long a post takes comments for, in days, before this is decided
|
|
15
|
+
* otherwise. WordPress's own default, and the age at which a post stops being
|
|
16
|
+
* a conversation and starts being a spam target.
|
|
17
|
+
*/
|
|
18
|
+
export declare const DEFAULT_COMMENTS_CLOSE_AFTER_DAYS = 14;
|
|
19
|
+
/** The site's half of the decision: the two settings that apply to every post. */
|
|
20
|
+
export interface CommentPolicy {
|
|
21
|
+
/** Whether the site takes comments at all. Off means off everywhere. */
|
|
22
|
+
enabled: boolean;
|
|
23
|
+
/** Days after a post's `date` that it stops taking them. Zero never closes. */
|
|
24
|
+
closeAfterDays: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Whether this document is taking native comments right now.
|
|
28
|
+
*
|
|
29
|
+
* The order is what the rules mean rather than what is cheapest to check:
|
|
30
|
+
*
|
|
31
|
+
* - The site switch is absolute. A site that has turned comments off has
|
|
32
|
+
* turned them off, and no post reopens itself past it.
|
|
33
|
+
* - A draft or a trashed document takes none either. Nobody can read it to
|
|
34
|
+
* comment on, so a form would only be a way of writing to a post that does
|
|
35
|
+
* not exist yet.
|
|
36
|
+
* - `comments: true` or `comments: false` in the front matter is the post's
|
|
37
|
+
* own answer and beats everything below it, in both directions.
|
|
38
|
+
* - A page is closed. A page is standing content — an about page, a colophon —
|
|
39
|
+
* and WordPress defaults them closed for the same reason.
|
|
40
|
+
* - Otherwise a post is open until it is `closeAfterDays` old, counted from
|
|
41
|
+
* its `date`. A post with no date has no age and stays open.
|
|
42
|
+
*
|
|
43
|
+
* None of this touches the fediverse. A reply, a like or a boost arrives
|
|
44
|
+
* because a remote server sent it, which nothing here can stop and nothing
|
|
45
|
+
* here should hide: a closed post still shows every one of them.
|
|
46
|
+
*/
|
|
47
|
+
export declare function commentsOpen(document: Document, policy: CommentPolicy, now?: Date): boolean;
|
|
48
|
+
/**
|
|
49
|
+
* The site's comment policy, as `content/_data/site.json` says it.
|
|
50
|
+
*
|
|
51
|
+
* Read off the site data rather than the typed settings so the public site can
|
|
52
|
+
* ask without reaching into the admin: the two keys are ordinary keys of that
|
|
53
|
+
* file, and a site that has never saved its settings gets the defaults —
|
|
54
|
+
* comments on, closing after a fortnight.
|
|
55
|
+
*/
|
|
56
|
+
export declare function commentPolicyOf(site: Record<string, unknown>): CommentPolicy;
|
|
57
|
+
//# sourceMappingURL=policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../src/comments/policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAEvD;;;;;;;;GAQG;AAEH,yEAAyE;AACzE,eAAO,MAAM,yBAAyB,aAAa,CAAC;AAEpD;;;;GAIG;AACH,eAAO,MAAM,iCAAiC,KAAK,CAAC;AAEpD,kFAAkF;AAClF,MAAM,WAAW,aAAa;IAC5B,wEAAwE;IACxE,OAAO,EAAE,OAAO,CAAC;IACjB,+EAA+E;IAC/E,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,aAAa,EACrB,GAAG,GAAE,IAAiB,GACrB,OAAO,CAiBT;AAKD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,aAAa,CAU5E"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* When a post is taking comments, and when it has stopped.
|
|
3
|
+
*
|
|
4
|
+
* WordPress spells this as three things that argue with each other — a site
|
|
5
|
+
* switch, an age, and a per-post override — and so does this. They are read in
|
|
6
|
+
* one place so the form under a post and the endpoint that refuses a
|
|
7
|
+
* submission can never disagree about whether a post is open, which is the
|
|
8
|
+
* only way a comment form can lie to somebody who has just typed a paragraph.
|
|
9
|
+
*/
|
|
10
|
+
/** The front-matter key a post opens or closes its own comments with. */
|
|
11
|
+
export const COMMENTS_FRONT_MATTER_KEY = 'comments';
|
|
12
|
+
/**
|
|
13
|
+
* How long a post takes comments for, in days, before this is decided
|
|
14
|
+
* otherwise. WordPress's own default, and the age at which a post stops being
|
|
15
|
+
* a conversation and starts being a spam target.
|
|
16
|
+
*/
|
|
17
|
+
export const DEFAULT_COMMENTS_CLOSE_AFTER_DAYS = 14;
|
|
18
|
+
/**
|
|
19
|
+
* Whether this document is taking native comments right now.
|
|
20
|
+
*
|
|
21
|
+
* The order is what the rules mean rather than what is cheapest to check:
|
|
22
|
+
*
|
|
23
|
+
* - The site switch is absolute. A site that has turned comments off has
|
|
24
|
+
* turned them off, and no post reopens itself past it.
|
|
25
|
+
* - A draft or a trashed document takes none either. Nobody can read it to
|
|
26
|
+
* comment on, so a form would only be a way of writing to a post that does
|
|
27
|
+
* not exist yet.
|
|
28
|
+
* - `comments: true` or `comments: false` in the front matter is the post's
|
|
29
|
+
* own answer and beats everything below it, in both directions.
|
|
30
|
+
* - A page is closed. A page is standing content — an about page, a colophon —
|
|
31
|
+
* and WordPress defaults them closed for the same reason.
|
|
32
|
+
* - Otherwise a post is open until it is `closeAfterDays` old, counted from
|
|
33
|
+
* its `date`. A post with no date has no age and stays open.
|
|
34
|
+
*
|
|
35
|
+
* None of this touches the fediverse. A reply, a like or a boost arrives
|
|
36
|
+
* because a remote server sent it, which nothing here can stop and nothing
|
|
37
|
+
* here should hide: a closed post still shows every one of them.
|
|
38
|
+
*/
|
|
39
|
+
export function commentsOpen(document, policy, now = new Date()) {
|
|
40
|
+
if (!policy.enabled)
|
|
41
|
+
return false;
|
|
42
|
+
if (document.draft)
|
|
43
|
+
return false;
|
|
44
|
+
const own = document.extra[COMMENTS_FRONT_MATTER_KEY];
|
|
45
|
+
if (own === false)
|
|
46
|
+
return false;
|
|
47
|
+
if (own === true)
|
|
48
|
+
return true;
|
|
49
|
+
if (document.type !== 'post')
|
|
50
|
+
return false;
|
|
51
|
+
if (policy.closeAfterDays <= 0)
|
|
52
|
+
return true;
|
|
53
|
+
if (document.date === undefined)
|
|
54
|
+
return true;
|
|
55
|
+
const published = new Date(document.date);
|
|
56
|
+
if (Number.isNaN(published.getTime()))
|
|
57
|
+
return true;
|
|
58
|
+
const closesAt = published.getTime() + policy.closeAfterDays * DAY_MS;
|
|
59
|
+
return now.getTime() < closesAt;
|
|
60
|
+
}
|
|
61
|
+
/** A day, in milliseconds. */
|
|
62
|
+
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
63
|
+
/**
|
|
64
|
+
* The site's comment policy, as `content/_data/site.json` says it.
|
|
65
|
+
*
|
|
66
|
+
* Read off the site data rather than the typed settings so the public site can
|
|
67
|
+
* ask without reaching into the admin: the two keys are ordinary keys of that
|
|
68
|
+
* file, and a site that has never saved its settings gets the defaults —
|
|
69
|
+
* comments on, closing after a fortnight.
|
|
70
|
+
*/
|
|
71
|
+
export function commentPolicyOf(site) {
|
|
72
|
+
const closeAfterDays = Number(site['commentsCloseAfterDays']);
|
|
73
|
+
return {
|
|
74
|
+
enabled: site['comments'] !== false,
|
|
75
|
+
closeAfterDays: Number.isInteger(closeAfterDays) && closeAfterDays >= 0
|
|
76
|
+
? closeAfterDays
|
|
77
|
+
: DEFAULT_COMMENTS_CLOSE_AFTER_DAYS,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/comments/policy.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,yEAAyE;AACzE,MAAM,CAAC,MAAM,yBAAyB,GAAG,UAAU,CAAC;AAEpD;;;;GAIG;AACH,MAAM,CAAC,MAAM,iCAAiC,GAAG,EAAE,CAAC;AAUpD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,YAAY,CAC1B,QAAkB,EAClB,MAAqB,EACrB,GAAG,GAAS,IAAI,IAAI,EAAE;IAEtB,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAClC,IAAI,QAAQ,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IAEjC,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACtD,IAAI,GAAG,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IAChC,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAE9B,IAAI,QAAQ,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC;IAC3C,IAAI,MAAM,CAAC,cAAc,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAE7C,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC1C,IAAI,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC;IAEnD,MAAM,QAAQ,GAAG,SAAS,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,cAAc,GAAG,MAAM,CAAC;IACtE,OAAO,GAAG,CAAC,OAAO,EAAE,GAAG,QAAQ,CAAC;AAClC,CAAC;AAED,8BAA8B;AAC9B,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEnC;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,IAA6B;IAC3D,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,CAAC;IAE9D,OAAO;QACL,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,KAAK,KAAK;QACnC,cAAc,EACZ,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,cAAc,IAAI,CAAC;YACrD,CAAC,CAAC,cAAc;YAChB,CAAC,CAAC,iCAAiC;KACxC,CAAC;AACJ,CAAC"}
|