@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,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a theme is, and what makes a directory one.
|
|
3
|
+
*
|
|
4
|
+
* This module is the only place that knows the packaged theme's path and the
|
|
5
|
+
* order the directories are searched in. The template environment, the
|
|
6
|
+
* `/theme/` asset finder, the mail environment and the per-render probe for
|
|
7
|
+
* the optional front-page and posts-page layouts all ask here, so there is one
|
|
8
|
+
* answer to "which theme is this render reading from" rather than four copies
|
|
9
|
+
* of the same two-element array (decision-15).
|
|
10
|
+
*
|
|
11
|
+
* The admin is deliberately not a theme. Its templates and its static files
|
|
12
|
+
* live at `admin/` with a loader of their own and are never on this path, so a
|
|
13
|
+
* site theme cannot shadow the login form or the CSRF field inside it
|
|
14
|
+
* (decision-4).
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* The theme that ships inside the package, resolved from this module rather
|
|
18
|
+
* than from the working directory, so it is found whether the CMS is running
|
|
19
|
+
* from `src/` under tsx or from `dist/` as an installed dependency.
|
|
20
|
+
*/
|
|
21
|
+
export declare const PACKAGED_THEME_DIR: string;
|
|
22
|
+
/** The file a directory declares itself a theme with. */
|
|
23
|
+
export declare const THEME_MANIFEST_FILE = "theme.json";
|
|
24
|
+
/**
|
|
25
|
+
* The only kind of theme there is.
|
|
26
|
+
*
|
|
27
|
+
* The field exists so a second kind — the admin, if it is ever made
|
|
28
|
+
* overridable — can slot in without the manifest format changing, and so a
|
|
29
|
+
* manifest that names a kind this CMS does not have is refused rather than
|
|
30
|
+
* loaded as a site theme by accident.
|
|
31
|
+
*/
|
|
32
|
+
export declare const SITE_THEME_KIND = "site";
|
|
33
|
+
/** What kinds of theme a manifest may declare. One, today. */
|
|
34
|
+
export type ThemeKind = typeof SITE_THEME_KIND;
|
|
35
|
+
/**
|
|
36
|
+
* One place a theme renders a menu, as its `theme.json` declares it.
|
|
37
|
+
*
|
|
38
|
+
* A theme decides where a menu can go, and the screen that edits menus cannot
|
|
39
|
+
* know what a theme wants (TASK-107). So the theme says: a `name`, which is
|
|
40
|
+
* the key a site stores that menu under in `site.json` and the key the
|
|
41
|
+
* template context carries it as, and a `label` for the person choosing which
|
|
42
|
+
* menu to fill in.
|
|
43
|
+
*/
|
|
44
|
+
export interface ThemeArea {
|
|
45
|
+
/** The menu's name: what `menus` is keyed by in `site.json` and in a render. */
|
|
46
|
+
readonly name: string;
|
|
47
|
+
/** What the Navigation screen calls this place, for a person to read. */
|
|
48
|
+
readonly label: string;
|
|
49
|
+
}
|
|
50
|
+
/** One theme directory, read and validated. */
|
|
51
|
+
export interface Theme {
|
|
52
|
+
/** The directory name, which is the theme's id and what a site.json names. */
|
|
53
|
+
readonly id: string;
|
|
54
|
+
/** Absolute path to the directory the manifest was read from. */
|
|
55
|
+
readonly dir: string;
|
|
56
|
+
/** The display name, for the admin's list. */
|
|
57
|
+
readonly name: string;
|
|
58
|
+
/** What the theme themes. Always {@link SITE_THEME_KIND} today. */
|
|
59
|
+
readonly kind: ThemeKind;
|
|
60
|
+
/** One line about the theme, when the manifest wrote one. */
|
|
61
|
+
readonly description?: string | undefined;
|
|
62
|
+
/**
|
|
63
|
+
* Where this theme renders a menu, in the order the manifest names them.
|
|
64
|
+
* Empty for a theme that declares none, which is every theme written before
|
|
65
|
+
* areas existed and every theme that renders no menu at all.
|
|
66
|
+
*/
|
|
67
|
+
readonly areas: readonly ThemeArea[];
|
|
68
|
+
}
|
|
69
|
+
/** A theme, or the reason the directory is not one. */
|
|
70
|
+
export type ThemeRead = {
|
|
71
|
+
readonly ok: true;
|
|
72
|
+
readonly theme: Theme;
|
|
73
|
+
} | {
|
|
74
|
+
readonly ok: false;
|
|
75
|
+
readonly reason: string;
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Read one directory as a theme.
|
|
79
|
+
*
|
|
80
|
+
* Every way of not being a theme comes back the same way — `ok: false` and a
|
|
81
|
+
* sentence saying why — because every caller has the same job with it: a
|
|
82
|
+
* listing greys the directory out, a chosen theme that stopped being one falls
|
|
83
|
+
* back to the packaged default with the reason logged, and the admin refuses
|
|
84
|
+
* to save it. None of them wants an exception, and a directory that is simply
|
|
85
|
+
* not a theme is not exceptional: a site's `themes/` will have a `.DS_Store`
|
|
86
|
+
* in it soon enough.
|
|
87
|
+
*/
|
|
88
|
+
export declare function readTheme(dir: string): ThemeRead;
|
|
89
|
+
/** A directory under the themes directory that turned out not to be a theme. */
|
|
90
|
+
export interface UnreadableTheme {
|
|
91
|
+
/** The directory name, as it sits on disk. */
|
|
92
|
+
readonly id: string;
|
|
93
|
+
/** Absolute path to it, so the screen can say where to go and look. */
|
|
94
|
+
readonly dir: string;
|
|
95
|
+
/** Why it is not a theme: {@link ThemeRead}'s reason. */
|
|
96
|
+
readonly reason: string;
|
|
97
|
+
}
|
|
98
|
+
/** What is in a site's themes directory: the themes, and the near misses. */
|
|
99
|
+
export interface SiteThemes {
|
|
100
|
+
/** Every directory that is a theme, by directory name. */
|
|
101
|
+
readonly themes: readonly Theme[];
|
|
102
|
+
/** Every directory that was meant to be one and is not. */
|
|
103
|
+
readonly unreadable: readonly UnreadableTheme[];
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Everything in one site's themes directory.
|
|
107
|
+
*
|
|
108
|
+
* Both halves come back because the Appearance screen draws both: a folder
|
|
109
|
+
* with a typo in its `theme.json` is listed with the reason rather than
|
|
110
|
+
* silently skipped, because a theme that has quietly vanished from the list is
|
|
111
|
+
* the hardest kind of mistake to find. The screen is the only caller —
|
|
112
|
+
* rendering asks {@link chooseTheme} about one name instead, and never reads
|
|
113
|
+
* the directory.
|
|
114
|
+
*
|
|
115
|
+
* Only a subdirectory is a candidate, and a hidden one is not even that: a
|
|
116
|
+
* `themes/` with a `.DS_Store`, a `README.md` or a `.git` in it is a site with
|
|
117
|
+
* no broken themes, not a site with three of them.
|
|
118
|
+
*
|
|
119
|
+
* A themes directory that is not there is an empty one. Nothing scaffolds it
|
|
120
|
+
* (decision-15), so a site that has never written a theme has no directory,
|
|
121
|
+
* and that is the ordinary state rather than a problem to report.
|
|
122
|
+
*/
|
|
123
|
+
export declare function listSiteThemes(themesDir: string): SiteThemes;
|
|
124
|
+
/**
|
|
125
|
+
* The theme directories one render reads from, in order: the theme the site
|
|
126
|
+
* has chosen first, the theme that ships in this package second.
|
|
127
|
+
*
|
|
128
|
+
* That is the whole override mechanism. A theme that ships only
|
|
129
|
+
* `layouts/post.njk` replaces the post layout and keeps receiving updates to
|
|
130
|
+
* every other template, and the same order decides a `/theme/` asset and a
|
|
131
|
+
* mail template. The chosen directory need not exist.
|
|
132
|
+
*
|
|
133
|
+
* A site that has chosen nothing passes nothing, and reads the packaged theme
|
|
134
|
+
* alone: an unchosen theme is never on the path, and the packaged one is never
|
|
135
|
+
* on it twice (decision-15).
|
|
136
|
+
*/
|
|
137
|
+
export declare function themeSearchPath(chosenThemeDir?: string): string[];
|
|
138
|
+
/**
|
|
139
|
+
* What a `theme` in `site.json` may be: the name of one directory inside the
|
|
140
|
+
* themes directory, and nothing that would reach outside it.
|
|
141
|
+
*
|
|
142
|
+
* The setting is a word somebody picks off a list, so this is about a
|
|
143
|
+
* hand-edited file rather than about an attacker — but the value decides a
|
|
144
|
+
* directory every template is then read out of, so it is checked before it is
|
|
145
|
+
* joined to a path rather than after.
|
|
146
|
+
*/
|
|
147
|
+
export declare function themeNameProblem(name: string): string | undefined;
|
|
148
|
+
/** Which theme a render reads from, and why it is that one. */
|
|
149
|
+
export interface ChosenTheme {
|
|
150
|
+
/** The site theme in use, or `undefined` when the packaged one is. */
|
|
151
|
+
readonly theme: Theme | undefined;
|
|
152
|
+
/** The directories to read, in order: {@link themeSearchPath}. */
|
|
153
|
+
readonly dirs: readonly string[];
|
|
154
|
+
/**
|
|
155
|
+
* Why the theme the site named is not the one in use, when it named one that
|
|
156
|
+
* is not there or is not a theme. `undefined` both for a site running the
|
|
157
|
+
* packaged theme on purpose and for one whose choice is working.
|
|
158
|
+
*/
|
|
159
|
+
readonly problem: string | undefined;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* The theme one site has chosen, resolved against its themes directory.
|
|
163
|
+
*
|
|
164
|
+
* A choice that cannot be honoured is the packaged theme and a sentence saying
|
|
165
|
+
* why, never an exception: a theme deleted from disk, or a `theme.json` broken
|
|
166
|
+
* by a hand edit, has to leave the site up and answering — the alternative is
|
|
167
|
+
* a site that 500s on every page because of a directory rename.
|
|
168
|
+
*/
|
|
169
|
+
export declare function chooseTheme(options: {
|
|
170
|
+
themesDir: string;
|
|
171
|
+
name: string;
|
|
172
|
+
}): ChosenTheme;
|
|
173
|
+
/** Where {@link createThemeSource} says what it could not do. */
|
|
174
|
+
export interface ThemeLogger {
|
|
175
|
+
warn(message: string): void;
|
|
176
|
+
}
|
|
177
|
+
/** The theme in use right now, asked afresh whenever anything renders. */
|
|
178
|
+
export interface ThemeSource {
|
|
179
|
+
/**
|
|
180
|
+
* The theme this render reads from.
|
|
181
|
+
*
|
|
182
|
+
* Cheap enough to call per render: it costs one read of the site's choice —
|
|
183
|
+
* which is itself cached against the `stat` of `site.json` — and one `stat`
|
|
184
|
+
* of the chosen theme's manifest.
|
|
185
|
+
*/
|
|
186
|
+
current(): ChosenTheme;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* The one thing that knows which theme a site is rendering through.
|
|
190
|
+
*
|
|
191
|
+
* It is a source rather than a value because the choice is a setting in
|
|
192
|
+
* `content/_data/site.json` (decision-9, decision-15): the Appearance screen
|
|
193
|
+
* writes that file, a hand edit writes the same file, and both have to reach
|
|
194
|
+
* the next request without a restart. So every consumer — the template
|
|
195
|
+
* environment, the `/theme/` assets, the mail templates — asks here per render
|
|
196
|
+
* instead of being handed a directory at boot.
|
|
197
|
+
*
|
|
198
|
+
* The result is cached against the choice and the `stat` of the chosen theme's
|
|
199
|
+
* manifest, so an unchanged site pays one `stat` per render and a theme
|
|
200
|
+
* edited, replaced or deleted under the running process is noticed on the next
|
|
201
|
+
* one. A choice that cannot be honoured is logged once, when the answer
|
|
202
|
+
* changes, rather than on every render: a site whose theme has been deleted
|
|
203
|
+
* should say so in the log and then serve pages, not fill the log with the
|
|
204
|
+
* same line.
|
|
205
|
+
*/
|
|
206
|
+
export declare function createThemeSource(options: {
|
|
207
|
+
/** Where the site's themes are: {@link ResolvedConfig.themesDir}. */
|
|
208
|
+
themesDir: string;
|
|
209
|
+
/** The site's choice, read per call. The empty string is the packaged theme. */
|
|
210
|
+
chosen: () => string;
|
|
211
|
+
/** Where a choice that could not be honoured is reported. Defaults to `console`. */
|
|
212
|
+
logger?: ThemeLogger | undefined;
|
|
213
|
+
}): ThemeSource;
|
|
214
|
+
/**
|
|
215
|
+
* The first theme on the path that ships one file, by absolute path, or
|
|
216
|
+
* `undefined` when none of them does.
|
|
217
|
+
*
|
|
218
|
+
* Nunjucks resolves its own templates through the same order, so this is for
|
|
219
|
+
* the two questions asked outside a render: whether a theme has written the
|
|
220
|
+
* optional front-page or posts-page layout, and which halves of a mail message
|
|
221
|
+
* exist. A path that climbs out of a theme directory finds nothing, so a
|
|
222
|
+
* caller passing a name through from a request cannot reach the file system
|
|
223
|
+
* around it.
|
|
224
|
+
*/
|
|
225
|
+
export declare function findThemeFile(themeDirs: readonly string[], relative: string): string | undefined;
|
|
226
|
+
//# sourceMappingURL=themes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"themes.d.ts","sourceRoot":"","sources":["../../src/web/themes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
/**
|
|
5
|
+
* Where a theme is, and what makes a directory one.
|
|
6
|
+
*
|
|
7
|
+
* This module is the only place that knows the packaged theme's path and the
|
|
8
|
+
* order the directories are searched in. The template environment, the
|
|
9
|
+
* `/theme/` asset finder, the mail environment and the per-render probe for
|
|
10
|
+
* the optional front-page and posts-page layouts all ask here, so there is one
|
|
11
|
+
* answer to "which theme is this render reading from" rather than four copies
|
|
12
|
+
* of the same two-element array (decision-15).
|
|
13
|
+
*
|
|
14
|
+
* The admin is deliberately not a theme. Its templates and its static files
|
|
15
|
+
* live at `admin/` with a loader of their own and are never on this path, so a
|
|
16
|
+
* site theme cannot shadow the login form or the CSRF field inside it
|
|
17
|
+
* (decision-4).
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* The theme that ships inside the package, resolved from this module rather
|
|
21
|
+
* than from the working directory, so it is found whether the CMS is running
|
|
22
|
+
* from `src/` under tsx or from `dist/` as an installed dependency.
|
|
23
|
+
*/
|
|
24
|
+
export const PACKAGED_THEME_DIR = fileURLToPath(new URL('../../themes/default/', import.meta.url));
|
|
25
|
+
/** The file a directory declares itself a theme with. */
|
|
26
|
+
export const THEME_MANIFEST_FILE = 'theme.json';
|
|
27
|
+
/**
|
|
28
|
+
* The only kind of theme there is.
|
|
29
|
+
*
|
|
30
|
+
* The field exists so a second kind — the admin, if it is ever made
|
|
31
|
+
* overridable — can slot in without the manifest format changing, and so a
|
|
32
|
+
* manifest that names a kind this CMS does not have is refused rather than
|
|
33
|
+
* loaded as a site theme by accident.
|
|
34
|
+
*/
|
|
35
|
+
export const SITE_THEME_KIND = 'site';
|
|
36
|
+
/**
|
|
37
|
+
* Read one directory as a theme.
|
|
38
|
+
*
|
|
39
|
+
* Every way of not being a theme comes back the same way — `ok: false` and a
|
|
40
|
+
* sentence saying why — because every caller has the same job with it: a
|
|
41
|
+
* listing greys the directory out, a chosen theme that stopped being one falls
|
|
42
|
+
* back to the packaged default with the reason logged, and the admin refuses
|
|
43
|
+
* to save it. None of them wants an exception, and a directory that is simply
|
|
44
|
+
* not a theme is not exceptional: a site's `themes/` will have a `.DS_Store`
|
|
45
|
+
* in it soon enough.
|
|
46
|
+
*/
|
|
47
|
+
export function readTheme(dir) {
|
|
48
|
+
const directory = path.resolve(dir);
|
|
49
|
+
const manifestFile = path.join(directory, THEME_MANIFEST_FILE);
|
|
50
|
+
let source;
|
|
51
|
+
try {
|
|
52
|
+
source = readFileSync(manifestFile, 'utf8');
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return { ok: false, reason: `There is no ${THEME_MANIFEST_FILE} in ${directory}.` };
|
|
56
|
+
}
|
|
57
|
+
let parsed;
|
|
58
|
+
try {
|
|
59
|
+
parsed = JSON.parse(source);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
63
|
+
return { ok: false, reason: `${manifestFile} is not valid JSON: ${detail}` };
|
|
64
|
+
}
|
|
65
|
+
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
|
|
66
|
+
return { ok: false, reason: `${manifestFile} is not a JSON object.` };
|
|
67
|
+
}
|
|
68
|
+
const manifest = parsed;
|
|
69
|
+
const name = manifest['name'];
|
|
70
|
+
if (typeof name !== 'string' || name.trim() === '') {
|
|
71
|
+
return { ok: false, reason: `${manifestFile} has no name.` };
|
|
72
|
+
}
|
|
73
|
+
const kind = manifest['kind'];
|
|
74
|
+
if (kind !== SITE_THEME_KIND) {
|
|
75
|
+
const named = typeof kind === 'string' ? `"${kind}"` : 'nothing';
|
|
76
|
+
return {
|
|
77
|
+
ok: false,
|
|
78
|
+
reason: `${manifestFile} declares kind ${named}, and the only theme kind is "${SITE_THEME_KIND}".`,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
const description = manifest['description'];
|
|
82
|
+
return {
|
|
83
|
+
ok: true,
|
|
84
|
+
theme: {
|
|
85
|
+
id: path.basename(directory),
|
|
86
|
+
dir: directory,
|
|
87
|
+
name: name.trim(),
|
|
88
|
+
kind: SITE_THEME_KIND,
|
|
89
|
+
...(typeof description === 'string' && description.trim() !== ''
|
|
90
|
+
? { description: description.trim() }
|
|
91
|
+
: {}),
|
|
92
|
+
areas: themeAreasOf(manifest['areas']),
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* An `areas` value as the areas it declares, ignoring anything that is not
|
|
98
|
+
* one.
|
|
99
|
+
*
|
|
100
|
+
* Tolerant where the name and the kind are strict, and deliberately so: a
|
|
101
|
+
* theme that got its areas wrong still renders a site, whereas one with no
|
|
102
|
+
* name or the wrong kind is not a theme at all. A declaration that cannot be
|
|
103
|
+
* read leaves the theme with no areas — the Navigation screen then offers
|
|
104
|
+
* nowhere to put a menu, which is visibly wrong and fixable, rather than the
|
|
105
|
+
* site 500ing over a typo in a manifest.
|
|
106
|
+
*
|
|
107
|
+
* A label is optional and falls back to the name, because an area with a name
|
|
108
|
+
* and no label is a theme that said where a menu goes and forgot to say it
|
|
109
|
+
* nicely. A name declared twice is one area: the manifest is a list only so
|
|
110
|
+
* that the order is the theme's to choose.
|
|
111
|
+
*/
|
|
112
|
+
function themeAreasOf(value) {
|
|
113
|
+
if (!Array.isArray(value))
|
|
114
|
+
return [];
|
|
115
|
+
const areas = [];
|
|
116
|
+
const seen = new Set();
|
|
117
|
+
for (const entry of value) {
|
|
118
|
+
if (typeof entry !== 'object' || entry === null)
|
|
119
|
+
continue;
|
|
120
|
+
const { name, label } = entry;
|
|
121
|
+
if (typeof name !== 'string')
|
|
122
|
+
continue;
|
|
123
|
+
const area = name.trim();
|
|
124
|
+
if (area === '' || seen.has(area))
|
|
125
|
+
continue;
|
|
126
|
+
seen.add(area);
|
|
127
|
+
const words = typeof label === 'string' ? label.trim() : '';
|
|
128
|
+
areas.push({ name: area, label: words === '' ? area : words });
|
|
129
|
+
}
|
|
130
|
+
return areas;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Everything in one site's themes directory.
|
|
134
|
+
*
|
|
135
|
+
* Both halves come back because the Appearance screen draws both: a folder
|
|
136
|
+
* with a typo in its `theme.json` is listed with the reason rather than
|
|
137
|
+
* silently skipped, because a theme that has quietly vanished from the list is
|
|
138
|
+
* the hardest kind of mistake to find. The screen is the only caller —
|
|
139
|
+
* rendering asks {@link chooseTheme} about one name instead, and never reads
|
|
140
|
+
* the directory.
|
|
141
|
+
*
|
|
142
|
+
* Only a subdirectory is a candidate, and a hidden one is not even that: a
|
|
143
|
+
* `themes/` with a `.DS_Store`, a `README.md` or a `.git` in it is a site with
|
|
144
|
+
* no broken themes, not a site with three of them.
|
|
145
|
+
*
|
|
146
|
+
* A themes directory that is not there is an empty one. Nothing scaffolds it
|
|
147
|
+
* (decision-15), so a site that has never written a theme has no directory,
|
|
148
|
+
* and that is the ordinary state rather than a problem to report.
|
|
149
|
+
*/
|
|
150
|
+
export function listSiteThemes(themesDir) {
|
|
151
|
+
const root = path.resolve(themesDir);
|
|
152
|
+
let entries;
|
|
153
|
+
try {
|
|
154
|
+
entries = readdirSync(root, { withFileTypes: true });
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
return { themes: [], unreadable: [] };
|
|
158
|
+
}
|
|
159
|
+
const themes = [];
|
|
160
|
+
const unreadable = [];
|
|
161
|
+
for (const entry of [...entries].sort((left, right) => left.name.localeCompare(right.name))) {
|
|
162
|
+
if (!entry.isDirectory() || entry.name.startsWith('.'))
|
|
163
|
+
continue;
|
|
164
|
+
const dir = path.join(root, entry.name);
|
|
165
|
+
const read = readTheme(dir);
|
|
166
|
+
if (read.ok)
|
|
167
|
+
themes.push(read.theme);
|
|
168
|
+
else
|
|
169
|
+
unreadable.push({ id: entry.name, dir, reason: read.reason });
|
|
170
|
+
}
|
|
171
|
+
return { themes, unreadable };
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* The theme directories one render reads from, in order: the theme the site
|
|
175
|
+
* has chosen first, the theme that ships in this package second.
|
|
176
|
+
*
|
|
177
|
+
* That is the whole override mechanism. A theme that ships only
|
|
178
|
+
* `layouts/post.njk` replaces the post layout and keeps receiving updates to
|
|
179
|
+
* every other template, and the same order decides a `/theme/` asset and a
|
|
180
|
+
* mail template. The chosen directory need not exist.
|
|
181
|
+
*
|
|
182
|
+
* A site that has chosen nothing passes nothing, and reads the packaged theme
|
|
183
|
+
* alone: an unchosen theme is never on the path, and the packaged one is never
|
|
184
|
+
* on it twice (decision-15).
|
|
185
|
+
*/
|
|
186
|
+
export function themeSearchPath(chosenThemeDir) {
|
|
187
|
+
return chosenThemeDir === undefined ? [PACKAGED_THEME_DIR] : [chosenThemeDir, PACKAGED_THEME_DIR];
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* What a `theme` in `site.json` may be: the name of one directory inside the
|
|
191
|
+
* themes directory, and nothing that would reach outside it.
|
|
192
|
+
*
|
|
193
|
+
* The setting is a word somebody picks off a list, so this is about a
|
|
194
|
+
* hand-edited file rather than about an attacker — but the value decides a
|
|
195
|
+
* directory every template is then read out of, so it is checked before it is
|
|
196
|
+
* joined to a path rather than after.
|
|
197
|
+
*/
|
|
198
|
+
export function themeNameProblem(name) {
|
|
199
|
+
const chosen = name.trim();
|
|
200
|
+
if (chosen === '')
|
|
201
|
+
return undefined;
|
|
202
|
+
if (chosen === '.' || chosen === '..' || /[/\\\0]/.test(chosen)) {
|
|
203
|
+
return `"${chosen}" is not a theme name: a theme is one directory inside the themes directory.`;
|
|
204
|
+
}
|
|
205
|
+
return undefined;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* The theme one site has chosen, resolved against its themes directory.
|
|
209
|
+
*
|
|
210
|
+
* A choice that cannot be honoured is the packaged theme and a sentence saying
|
|
211
|
+
* why, never an exception: a theme deleted from disk, or a `theme.json` broken
|
|
212
|
+
* by a hand edit, has to leave the site up and answering — the alternative is
|
|
213
|
+
* a site that 500s on every page because of a directory rename.
|
|
214
|
+
*/
|
|
215
|
+
export function chooseTheme(options) {
|
|
216
|
+
const name = options.name.trim();
|
|
217
|
+
if (name === '')
|
|
218
|
+
return { theme: undefined, dirs: themeSearchPath(), problem: undefined };
|
|
219
|
+
const badName = themeNameProblem(name);
|
|
220
|
+
if (badName !== undefined) {
|
|
221
|
+
return { theme: undefined, dirs: themeSearchPath(), problem: badName };
|
|
222
|
+
}
|
|
223
|
+
const read = readTheme(path.join(options.themesDir, name));
|
|
224
|
+
if (!read.ok) {
|
|
225
|
+
return {
|
|
226
|
+
theme: undefined,
|
|
227
|
+
dirs: themeSearchPath(),
|
|
228
|
+
problem: `The theme "${name}" is not there: ${read.reason}`,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
return { theme: read.theme, dirs: themeSearchPath(read.theme.dir), problem: undefined };
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* The one thing that knows which theme a site is rendering through.
|
|
235
|
+
*
|
|
236
|
+
* It is a source rather than a value because the choice is a setting in
|
|
237
|
+
* `content/_data/site.json` (decision-9, decision-15): the Appearance screen
|
|
238
|
+
* writes that file, a hand edit writes the same file, and both have to reach
|
|
239
|
+
* the next request without a restart. So every consumer — the template
|
|
240
|
+
* environment, the `/theme/` assets, the mail templates — asks here per render
|
|
241
|
+
* instead of being handed a directory at boot.
|
|
242
|
+
*
|
|
243
|
+
* The result is cached against the choice and the `stat` of the chosen theme's
|
|
244
|
+
* manifest, so an unchanged site pays one `stat` per render and a theme
|
|
245
|
+
* edited, replaced or deleted under the running process is noticed on the next
|
|
246
|
+
* one. A choice that cannot be honoured is logged once, when the answer
|
|
247
|
+
* changes, rather than on every render: a site whose theme has been deleted
|
|
248
|
+
* should say so in the log and then serve pages, not fill the log with the
|
|
249
|
+
* same line.
|
|
250
|
+
*/
|
|
251
|
+
export function createThemeSource(options) {
|
|
252
|
+
const logger = options.logger ?? console;
|
|
253
|
+
let cached;
|
|
254
|
+
let cachedKey;
|
|
255
|
+
let reported;
|
|
256
|
+
/**
|
|
257
|
+
* What would make the answer different: the name chosen, and the state of
|
|
258
|
+
* that theme's manifest. The modification time alone is not enough, for the
|
|
259
|
+
* reason it is not in {@link createSiteDataSource}: a filesystem rounds it,
|
|
260
|
+
* and a theme replaced wholesale changes the inode rather than the time.
|
|
261
|
+
*/
|
|
262
|
+
function key(name) {
|
|
263
|
+
if (name === '')
|
|
264
|
+
return '';
|
|
265
|
+
try {
|
|
266
|
+
const stats = statSync(path.join(options.themesDir, name, THEME_MANIFEST_FILE));
|
|
267
|
+
return `${name}:${String(stats.mtimeMs)}:${String(stats.size)}:${String(stats.ino)}`;
|
|
268
|
+
}
|
|
269
|
+
catch {
|
|
270
|
+
return `${name}:missing`;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return {
|
|
274
|
+
current() {
|
|
275
|
+
const name = options.chosen().trim();
|
|
276
|
+
const current = key(name);
|
|
277
|
+
if (cached !== undefined && current === cachedKey)
|
|
278
|
+
return cached;
|
|
279
|
+
cachedKey = current;
|
|
280
|
+
cached = chooseTheme({ themesDir: options.themesDir, name });
|
|
281
|
+
if (cached.problem !== undefined && cached.problem !== reported) {
|
|
282
|
+
logger.warn(`${cached.problem} The packaged theme is being used instead.`);
|
|
283
|
+
}
|
|
284
|
+
reported = cached.problem;
|
|
285
|
+
return cached;
|
|
286
|
+
},
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* The first theme on the path that ships one file, by absolute path, or
|
|
291
|
+
* `undefined` when none of them does.
|
|
292
|
+
*
|
|
293
|
+
* Nunjucks resolves its own templates through the same order, so this is for
|
|
294
|
+
* the two questions asked outside a render: whether a theme has written the
|
|
295
|
+
* optional front-page or posts-page layout, and which halves of a mail message
|
|
296
|
+
* exist. A path that climbs out of a theme directory finds nothing, so a
|
|
297
|
+
* caller passing a name through from a request cannot reach the file system
|
|
298
|
+
* around it.
|
|
299
|
+
*/
|
|
300
|
+
export function findThemeFile(themeDirs, relative) {
|
|
301
|
+
if (relative === '' || relative.includes('\0'))
|
|
302
|
+
return undefined;
|
|
303
|
+
const segments = relative.split('/').filter((segment) => segment !== '');
|
|
304
|
+
for (const directory of themeDirs) {
|
|
305
|
+
const root = path.resolve(directory);
|
|
306
|
+
const file = path.resolve(root, ...segments);
|
|
307
|
+
if (file !== root && !file.startsWith(root + path.sep))
|
|
308
|
+
continue;
|
|
309
|
+
if (existsSync(file))
|
|
310
|
+
return file;
|
|
311
|
+
}
|
|
312
|
+
return undefined;
|
|
313
|
+
}
|
|
314
|
+
//# sourceMappingURL=themes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"themes.js","sourceRoot":"","sources":["../../src/web/themes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finding out where to send a webmention.
|
|
3
|
+
*
|
|
4
|
+
* The W3C spec fixes the order and it matters, because a page may advertise
|
|
5
|
+
* two: the HTTP `Link` header first, then the first `<link>` **or** `<a>`
|
|
6
|
+
* carrying `rel="webmention"` in document order — one search over both, not
|
|
7
|
+
* one search each. Whatever is found is resolved against the URL the request
|
|
8
|
+
* actually ended at, so a target that redirects to its canonical home
|
|
9
|
+
* advertises that home's endpoint rather than a path under the old one.
|
|
10
|
+
*/
|
|
11
|
+
/** How long one discovery request is given before it is abandoned. */
|
|
12
|
+
export declare const DISCOVERY_TIMEOUT_MS = 10000;
|
|
13
|
+
/** How much of a target page is read while looking for its endpoint. */
|
|
14
|
+
export declare const DISCOVERY_MAX_BYTES = 1000000;
|
|
15
|
+
/** What a sender says it is. */
|
|
16
|
+
export declare const WEBMENTION_USER_AGENT = "Geekity/1.0 (+https://github.com/andrewshell/geekity)";
|
|
17
|
+
/**
|
|
18
|
+
* The Webmention endpoint a page advertises, or `undefined` when it advertises
|
|
19
|
+
* none — which is most pages, and is not an error.
|
|
20
|
+
*
|
|
21
|
+
* Nothing throws: a target that times out, refuses the connection or answers
|
|
22
|
+
* an error is a target with no endpoint as far as the sender is concerned, and
|
|
23
|
+
* the caller records that rather than stopping.
|
|
24
|
+
*/
|
|
25
|
+
export declare function discoverEndpoint(target: string): Promise<string | undefined>;
|
|
26
|
+
/**
|
|
27
|
+
* The endpoint one or more `Link` headers name, or `undefined`.
|
|
28
|
+
*
|
|
29
|
+
* A header may carry several links separated by commas and each may name
|
|
30
|
+
* several relations, so both are split. Splitting on commas that are not
|
|
31
|
+
* inside angle brackets or quotes is what keeps a URL holding a comma — which
|
|
32
|
+
* is legal — from being torn in half.
|
|
33
|
+
*/
|
|
34
|
+
export declare function endpointInHeader(header: string | null, base: string): string | undefined;
|
|
35
|
+
/**
|
|
36
|
+
* The endpoint a page's markup names, or `undefined`.
|
|
37
|
+
*
|
|
38
|
+
* One walk over every element rather than one for `<link>` and another for
|
|
39
|
+
* `<a>`: the spec asks for the first of either in document order, and two
|
|
40
|
+
* walks would answer with whichever kind was searched for first.
|
|
41
|
+
*/
|
|
42
|
+
export declare function endpointInHtml(html: string, base: string): string | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* A response body, up to {@link DISCOVERY_MAX_BYTES}.
|
|
45
|
+
*
|
|
46
|
+
* A cap rather than `response.text()`, because the page at the other end is a
|
|
47
|
+
* stranger's and nothing stops it being a gigabyte. What is read is more than
|
|
48
|
+
* enough markup for a `<link>` in the head.
|
|
49
|
+
*/
|
|
50
|
+
export declare function readCapped(response: Response): Promise<string>;
|
|
51
|
+
//# sourceMappingURL=discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/webmention/discovery.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AAEH,sEAAsE;AACtE,eAAO,MAAM,oBAAoB,QAAS,CAAC;AAE3C,wEAAwE;AACxE,eAAO,MAAM,mBAAmB,UAAY,CAAC;AAE7C,gCAAgC;AAChC,eAAO,MAAM,qBAAqB,0DAA0D,CAAC;AAE7F;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAkClF;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAexF;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAW7E;AAsCD;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CA0BpE"}
|