@geekity/cms 0.30.0 → 0.32.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 +26 -4266
- package/admin/components/badge.njk +4 -0
- package/admin/components/fields.njk +41 -24
- package/admin/components/job-status.njk +45 -0
- package/admin/components/setting-fields.njk +38 -0
- package/admin/layouts/settings-page.njk +16 -0
- package/admin/pages/comments/all.njk +1 -2
- package/admin/pages/documents/editor.njk +17 -15
- package/admin/pages/documents/syndication.njk +4 -4
- package/admin/pages/federation/followers.njk +56 -6
- package/admin/pages/federation/settings.njk +1 -1
- package/admin/pages/media/library.njk +52 -3
- package/admin/pages/navigation/menus.njk +2 -2
- package/admin/pages/plugins/screen.njk +5 -46
- package/admin/pages/settings/discussion.njk +76 -47
- package/admin/pages/settings/email.njk +75 -47
- package/admin/pages/settings/general.njk +15 -15
- package/admin/pages/settings/permalinks.njk +8 -8
- package/admin/pages/settings/privacy.njk +6 -6
- package/admin/pages/settings/reading.njk +36 -36
- package/admin/pages/tools/dev-mode.njk +29 -3
- package/admin/pages/tools/export.njk +89 -0
- package/admin/pages/tools/maintenance.njk +51 -0
- package/admin/pages/users/apps.njk +2 -2
- package/admin/pages/users/edit.njk +3 -3
- package/admin/pages/users/new.njk +2 -2
- package/admin/static/admin.css +80 -0
- package/dist/access-log.d.ts +2 -10
- package/dist/access-log.d.ts.map +1 -1
- package/dist/access-log.js +1 -1
- package/dist/access-log.js.map +1 -1
- package/dist/{web → admin}/admin-bar.d.ts +3 -2
- package/dist/admin/admin-bar.d.ts.map +1 -0
- package/dist/{web → admin}/admin-bar.js +20 -17
- package/dist/admin/admin-bar.js.map +1 -0
- package/dist/{indieauth → admin}/app-activity.d.ts +2 -2
- package/dist/admin/app-activity.d.ts.map +1 -0
- package/dist/{indieauth → admin}/app-activity.js +6 -7
- package/dist/admin/app-activity.js.map +1 -0
- package/dist/admin/appearance.d.ts +4 -8
- package/dist/admin/appearance.d.ts.map +1 -1
- package/dist/admin/appearance.js +19 -20
- package/dist/admin/appearance.js.map +1 -1
- package/dist/admin/assets.d.ts +1 -8
- package/dist/admin/assets.d.ts.map +1 -1
- package/dist/admin/assets.js +2 -9
- package/dist/admin/assets.js.map +1 -1
- package/dist/admin/comments.d.ts +2 -2
- package/dist/admin/comments.d.ts.map +1 -1
- package/dist/admin/comments.js +17 -19
- package/dist/admin/comments.js.map +1 -1
- package/dist/admin/confirm-password.d.ts +4 -0
- package/dist/admin/confirm-password.d.ts.map +1 -0
- package/dist/admin/confirm-password.js +11 -0
- package/dist/admin/confirm-password.js.map +1 -0
- package/dist/{indieauth → admin}/connected-apps.d.ts +2 -2
- package/dist/admin/connected-apps.d.ts.map +1 -0
- package/dist/{indieauth → admin}/connected-apps.js +33 -39
- package/dist/admin/connected-apps.js.map +1 -0
- package/dist/admin/credentials.js +1 -1
- package/dist/admin/credentials.js.map +1 -1
- package/dist/admin/dev-mode.d.ts +1 -1
- package/dist/admin/dev-mode.d.ts.map +1 -1
- package/dist/admin/dev-mode.js +35 -10
- package/dist/admin/dev-mode.js.map +1 -1
- package/dist/admin/documents.d.ts +16 -301
- package/dist/admin/documents.d.ts.map +1 -1
- package/dist/admin/documents.js +94 -1040
- package/dist/admin/documents.js.map +1 -1
- package/dist/admin/editor-actions.d.ts +3 -2
- package/dist/admin/editor-actions.d.ts.map +1 -1
- package/dist/admin/editor-actions.js +8 -9
- package/dist/admin/editor-actions.js.map +1 -1
- package/dist/admin/editor-fields.d.ts +45 -0
- package/dist/admin/editor-fields.d.ts.map +1 -0
- package/dist/admin/editor-fields.js +71 -0
- package/dist/admin/editor-fields.js.map +1 -0
- package/dist/admin/editor-layout.d.ts +2 -10
- package/dist/admin/editor-layout.d.ts.map +1 -1
- package/dist/admin/editor-layout.js +2 -2
- package/dist/admin/editor-layout.js.map +1 -1
- package/dist/admin/export.d.ts +10 -0
- package/dist/admin/export.d.ts.map +1 -0
- package/dist/admin/export.js +72 -0
- package/dist/admin/export.js.map +1 -0
- package/dist/admin/federation.d.ts +6 -17
- package/dist/admin/federation.d.ts.map +1 -1
- package/dist/admin/federation.js +49 -104
- package/dist/admin/federation.js.map +1 -1
- package/dist/admin/flash.d.ts +2 -2
- package/dist/admin/flash.d.ts.map +1 -1
- package/dist/admin/headers.d.ts +1 -1
- package/dist/admin/headers.d.ts.map +1 -1
- package/dist/admin/headers.js +1 -1
- package/dist/admin/headers.js.map +1 -1
- package/dist/admin/index.d.ts +36 -21
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +26 -14
- package/dist/admin/index.js.map +1 -1
- package/dist/{indieauth/consent.d.ts → admin/indieauth-consent.d.ts} +4 -4
- package/dist/admin/indieauth-consent.d.ts.map +1 -0
- package/dist/{indieauth/consent.js → admin/indieauth-consent.js} +20 -23
- package/dist/admin/indieauth-consent.js.map +1 -0
- package/dist/admin/job-status.d.ts +25 -0
- package/dist/admin/job-status.d.ts.map +1 -0
- package/dist/admin/job-status.js +53 -0
- package/dist/admin/job-status.js.map +1 -0
- package/dist/admin/legacy-migrations.d.ts +131 -0
- package/dist/admin/legacy-migrations.d.ts.map +1 -0
- package/dist/admin/legacy-migrations.js +236 -0
- package/dist/admin/legacy-migrations.js.map +1 -0
- package/dist/admin/maintenance.d.ts +9 -0
- package/dist/admin/maintenance.d.ts.map +1 -0
- package/dist/admin/maintenance.js +42 -0
- package/dist/admin/maintenance.js.map +1 -0
- package/dist/admin/media.d.ts +8 -109
- package/dist/admin/media.d.ts.map +1 -1
- package/dist/admin/media.js +35 -188
- package/dist/admin/media.js.map +1 -1
- package/dist/admin/menu.d.ts.map +1 -1
- package/dist/admin/menu.js +11 -7
- package/dist/admin/menu.js.map +1 -1
- package/dist/admin/messages.d.ts +1 -1
- package/dist/admin/messages.d.ts.map +1 -1
- package/dist/admin/messages.js +11 -14
- package/dist/admin/messages.js.map +1 -1
- package/dist/admin/navigation.d.ts +3 -3
- package/dist/admin/navigation.d.ts.map +1 -1
- package/dist/admin/navigation.js +34 -33
- package/dist/admin/navigation.js.map +1 -1
- package/dist/admin/personal-data.d.ts +1 -1
- package/dist/admin/personal-data.d.ts.map +1 -1
- package/dist/admin/personal-data.js +3 -6
- package/dist/admin/personal-data.js.map +1 -1
- package/dist/admin/plugins.d.ts +1 -1
- package/dist/admin/plugins.d.ts.map +1 -1
- package/dist/admin/plugins.js +28 -79
- package/dist/admin/plugins.js.map +1 -1
- package/dist/admin/preview.d.ts +2 -1
- package/dist/admin/preview.d.ts.map +1 -1
- package/dist/admin/preview.js +31 -36
- package/dist/admin/preview.js.map +1 -1
- package/dist/admin/recovery.d.ts +3 -3
- package/dist/admin/recovery.d.ts.map +1 -1
- package/dist/admin/recovery.js +12 -14
- package/dist/admin/recovery.js.map +1 -1
- package/dist/admin/routes.d.ts +1 -3
- package/dist/admin/routes.d.ts.map +1 -1
- package/dist/admin/routes.js +34 -29
- package/dist/admin/routes.js.map +1 -1
- package/dist/admin/setting-overrides.d.ts +4 -0
- package/dist/admin/setting-overrides.d.ts.map +1 -0
- package/dist/admin/setting-overrides.js +24 -0
- package/dist/admin/setting-overrides.js.map +1 -0
- package/dist/admin/settings-discussion.d.ts +6 -4
- package/dist/admin/settings-discussion.d.ts.map +1 -1
- package/dist/admin/settings-discussion.js +79 -46
- package/dist/admin/settings-discussion.js.map +1 -1
- package/dist/admin/settings-email.d.ts +12 -9
- package/dist/admin/settings-email.d.ts.map +1 -1
- package/dist/admin/settings-email.js +94 -80
- package/dist/admin/settings-email.js.map +1 -1
- package/dist/admin/settings-federation.d.ts +0 -7
- package/dist/admin/settings-federation.d.ts.map +1 -1
- package/dist/admin/settings-federation.js +0 -36
- package/dist/admin/settings-federation.js.map +1 -1
- package/dist/admin/settings-fields.d.ts +32 -0
- package/dist/admin/settings-fields.d.ts.map +1 -0
- package/dist/admin/settings-fields.js +368 -0
- package/dist/admin/settings-fields.js.map +1 -0
- package/dist/admin/settings-general.d.ts.map +1 -1
- package/dist/admin/settings-general.js +17 -23
- package/dist/admin/settings-general.js.map +1 -1
- package/dist/admin/settings-page.d.ts +5 -32
- package/dist/admin/settings-page.d.ts.map +1 -1
- package/dist/admin/settings-page.js +39 -55
- package/dist/admin/settings-page.js.map +1 -1
- package/dist/admin/settings-pages.d.ts +1 -1
- package/dist/admin/settings-pages.d.ts.map +1 -1
- package/dist/admin/settings-permalinks.js +3 -3
- package/dist/admin/settings-permalinks.js.map +1 -1
- package/dist/admin/settings-privacy.js +1 -1
- package/dist/admin/settings-privacy.js.map +1 -1
- package/dist/admin/settings-reading.d.ts +2 -2
- package/dist/admin/settings-reading.d.ts.map +1 -1
- package/dist/admin/settings-reading.js +17 -16
- package/dist/admin/settings-reading.js.map +1 -1
- package/dist/admin/settings-renderer.d.ts +32 -0
- package/dist/admin/settings-renderer.d.ts.map +1 -0
- package/dist/admin/settings-renderer.js +79 -0
- package/dist/admin/settings-renderer.js.map +1 -0
- package/dist/admin/settings.d.ts +0 -579
- package/dist/admin/settings.d.ts.map +1 -1
- package/dist/admin/settings.js +1 -1155
- package/dist/admin/settings.js.map +1 -1
- package/dist/admin/site-setting-edit.d.ts +4 -0
- package/dist/admin/site-setting-edit.d.ts.map +1 -0
- package/dist/admin/site-setting-edit.js +20 -0
- package/dist/admin/site-setting-edit.js.map +1 -0
- package/dist/admin/syndication-targets.d.ts +1 -1
- package/dist/admin/syndication-targets.d.ts.map +1 -1
- package/dist/admin/syndication-targets.js +11 -15
- package/dist/admin/syndication-targets.js.map +1 -1
- package/dist/admin/taxonomy.d.ts +2 -2
- package/dist/admin/taxonomy.d.ts.map +1 -1
- package/dist/admin/taxonomy.js +17 -29
- package/dist/admin/taxonomy.js.map +1 -1
- package/dist/admin/templates.d.ts +2 -0
- package/dist/admin/templates.d.ts.map +1 -1
- package/dist/admin/templates.js +3 -1
- package/dist/admin/templates.js.map +1 -1
- package/dist/admin/tools.d.ts +4 -4
- package/dist/admin/tools.d.ts.map +1 -1
- package/dist/admin/tools.js +3 -6
- package/dist/admin/tools.js.map +1 -1
- package/dist/admin/uploads.d.ts +1 -106
- package/dist/admin/uploads.d.ts.map +1 -1
- package/dist/admin/uploads.js +2 -191
- package/dist/admin/uploads.js.map +1 -1
- package/dist/admin/users.d.ts +20 -15
- package/dist/admin/users.d.ts.map +1 -1
- package/dist/admin/users.js +84 -81
- package/dist/admin/users.js.map +1 -1
- package/dist/avatars/avatars.d.ts +2 -4
- package/dist/avatars/avatars.d.ts.map +1 -1
- package/dist/avatars/avatars.js +15 -19
- package/dist/avatars/avatars.js.map +1 -1
- package/dist/avatars/index.d.ts +1 -2
- package/dist/avatars/index.d.ts.map +1 -1
- package/dist/avatars/index.js +1 -2
- package/dist/avatars/index.js.map +1 -1
- package/dist/cache.d.ts +4 -4
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js +13 -9
- package/dist/cache.js.map +1 -1
- package/dist/cli.d.ts +2 -33
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +729 -344
- package/dist/cli.js.map +1 -1
- package/dist/cms/app.d.ts +11 -0
- package/dist/cms/app.d.ts.map +1 -0
- package/dist/cms/app.js +126 -0
- package/dist/cms/app.js.map +1 -0
- package/dist/cms/boot.d.ts +26 -0
- package/dist/cms/boot.d.ts.map +1 -0
- package/dist/cms/boot.js +128 -0
- package/dist/cms/boot.js.map +1 -0
- package/dist/cms/create.d.ts +272 -0
- package/dist/cms/create.d.ts.map +1 -0
- package/dist/cms/create.js +181 -0
- package/dist/cms/create.js.map +1 -0
- package/dist/cms/lifecycle.d.ts +11 -0
- package/dist/cms/lifecycle.d.ts.map +1 -0
- package/dist/cms/lifecycle.js +15 -0
- package/dist/cms/lifecycle.js.map +1 -0
- package/dist/{web/errors.d.ts → cms/server-error.d.ts} +2 -8
- package/dist/cms/server-error.d.ts.map +1 -0
- package/dist/{web/errors.js → cms/server-error.js} +4 -14
- package/dist/cms/server-error.js.map +1 -0
- package/dist/cms/services.d.ts +57 -0
- package/dist/cms/services.d.ts.map +1 -0
- package/dist/cms/services.js +410 -0
- package/dist/cms/services.js.map +1 -0
- package/dist/cms/site-records.d.ts +4 -0
- package/dist/cms/site-records.d.ts.map +1 -0
- package/dist/cms/site-records.js +13 -0
- package/dist/cms/site-records.js.map +1 -0
- package/dist/comments/akismet.d.ts +14 -47
- package/dist/comments/akismet.d.ts.map +1 -1
- package/dist/comments/akismet.js +30 -71
- package/dist/comments/akismet.js.map +1 -1
- package/dist/comments/conversation.d.ts +340 -0
- package/dist/comments/conversation.d.ts.map +1 -0
- package/dist/comments/conversation.js +51 -0
- package/dist/comments/conversation.js.map +1 -0
- package/dist/comments/form.d.ts +2 -2
- package/dist/comments/form.d.ts.map +1 -1
- package/dist/comments/form.js +2 -2
- package/dist/comments/form.js.map +1 -1
- package/dist/comments/index.d.ts +15 -9
- package/dist/comments/index.d.ts.map +1 -1
- package/dist/comments/index.js +9 -6
- package/dist/comments/index.js.map +1 -1
- package/dist/comments/intake.d.ts +147 -0
- package/dist/comments/intake.d.ts.map +1 -0
- package/dist/comments/intake.js +161 -0
- package/dist/comments/intake.js.map +1 -0
- package/dist/comments/markdown.d.ts.map +1 -1
- package/dist/comments/markdown.js +2 -9
- package/dist/comments/markdown.js.map +1 -1
- package/dist/comments/migrations.d.ts +45 -0
- package/dist/comments/migrations.d.ts.map +1 -0
- package/dist/comments/migrations.js +194 -0
- package/dist/comments/migrations.js.map +1 -0
- package/dist/comments/moderate.d.ts +2 -2
- package/dist/comments/moderate.d.ts.map +1 -1
- package/dist/comments/moderate.js +3 -13
- package/dist/comments/moderate.js.map +1 -1
- package/dist/comments/page-form.d.ts +52 -0
- package/dist/comments/page-form.d.ts.map +1 -0
- package/dist/comments/page-form.js +62 -0
- package/dist/comments/page-form.js.map +1 -0
- package/dist/comments/policy.d.ts +24 -35
- package/dist/comments/policy.d.ts.map +1 -1
- package/dist/comments/policy.js +16 -38
- package/dist/comments/policy.js.map +1 -1
- package/dist/comments/records.d.ts +17 -195
- package/dist/comments/records.d.ts.map +1 -1
- package/dist/comments/records.js +24 -394
- package/dist/comments/records.js.map +1 -1
- package/dist/comments/reply-notices.d.ts +10 -11
- package/dist/comments/reply-notices.d.ts.map +1 -1
- package/dist/comments/reply-notices.js +32 -20
- package/dist/comments/reply-notices.js.map +1 -1
- package/dist/comments/reply-post.d.ts +2 -2
- package/dist/comments/reply-post.d.ts.map +1 -1
- package/dist/comments/reply-post.js +8 -7
- package/dist/comments/reply-post.js.map +1 -1
- package/dist/comments/routes.d.ts +3 -3
- package/dist/comments/routes.d.ts.map +1 -1
- package/dist/comments/routes.js +19 -31
- package/dist/comments/routes.js.map +1 -1
- package/dist/comments/submission.d.ts +5 -102
- package/dist/comments/submission.d.ts.map +1 -1
- package/dist/comments/submission.js +5 -22
- package/dist/comments/submission.js.map +1 -1
- package/dist/comments/viewer.d.ts +1 -25
- package/dist/comments/viewer.d.ts.map +1 -1
- package/dist/comments/viewer.js +1 -44
- package/dist/comments/viewer.js.map +1 -1
- package/dist/config-loader.d.ts +35 -0
- package/dist/config-loader.d.ts.map +1 -0
- package/dist/config-loader.js +117 -0
- package/dist/config-loader.js.map +1 -0
- package/dist/config.d.ts +99 -51
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +137 -181
- package/dist/config.js.map +1 -1
- package/dist/contact/delivery.d.ts +3 -5
- package/dist/contact/delivery.d.ts.map +1 -1
- package/dist/contact/delivery.js +5 -14
- package/dist/contact/delivery.js.map +1 -1
- package/dist/contact/form.d.ts +2 -4
- package/dist/contact/form.d.ts.map +1 -1
- package/dist/contact/form.js +3 -4
- package/dist/contact/form.js.map +1 -1
- package/dist/contact/index.d.ts +3 -3
- package/dist/contact/index.d.ts.map +1 -1
- package/dist/contact/index.js +3 -3
- package/dist/contact/index.js.map +1 -1
- package/dist/contact/records.d.ts +0 -2
- package/dist/contact/records.d.ts.map +1 -1
- package/dist/contact/records.js +11 -16
- package/dist/contact/records.js.map +1 -1
- package/dist/contact/submission.d.ts +2 -2
- package/dist/contact/submission.d.ts.map +1 -1
- package/dist/contact/submission.js +7 -16
- package/dist/contact/submission.js.map +1 -1
- package/dist/{images → content}/alt-text.d.ts +1 -1
- package/dist/content/alt-text.d.ts.map +1 -0
- package/dist/{images → content}/alt-text.js +3 -5
- package/dist/content/alt-text.js.map +1 -0
- package/dist/content/authors.d.ts +79 -0
- package/dist/content/authors.d.ts.map +1 -0
- package/dist/content/authors.js +106 -0
- package/dist/content/authors.js.map +1 -0
- package/dist/content/citation.d.ts +4 -0
- package/dist/content/citation.d.ts.map +1 -1
- package/dist/content/citation.js +3 -0
- package/dist/content/citation.js.map +1 -1
- package/dist/content/comments.d.ts +3 -0
- package/dist/content/comments.d.ts.map +1 -0
- package/dist/content/comments.js +3 -0
- package/dist/content/comments.js.map +1 -0
- package/dist/content/contact.d.ts +3 -0
- package/dist/content/contact.d.ts.map +1 -0
- package/dist/content/contact.js +3 -0
- package/dist/content/contact.js.map +1 -0
- package/dist/content/document-form.d.ts +197 -0
- package/dist/content/document-form.d.ts.map +1 -0
- package/dist/content/document-form.js +201 -0
- package/dist/content/document-form.js.map +1 -0
- package/dist/content/document-kind.d.ts +55 -0
- package/dist/content/document-kind.d.ts.map +1 -0
- package/dist/content/document-kind.js +30 -0
- package/dist/content/document-kind.js.map +1 -0
- package/dist/{admin/enclosure-field.d.ts → content/enclosure-form.d.ts} +14 -34
- package/dist/content/enclosure-form.d.ts.map +1 -0
- package/dist/{admin/enclosure-field.js → content/enclosure-form.js} +43 -81
- package/dist/content/enclosure-form.js.map +1 -0
- package/dist/content/enclosure.d.ts.map +1 -1
- package/dist/content/enclosure.js +3 -4
- package/dist/content/enclosure.js.map +1 -1
- package/dist/{admin/event-field.d.ts → content/event-form.d.ts} +6 -5
- package/dist/content/event-form.d.ts.map +1 -0
- package/dist/{admin/event-field.js → content/event-form.js} +45 -12
- package/dist/content/event-form.js.map +1 -0
- package/dist/content/excerpt.d.ts +26 -0
- package/dist/content/excerpt.d.ts.map +1 -0
- package/dist/content/excerpt.js +46 -0
- package/dist/content/excerpt.js.map +1 -0
- package/dist/content/form-error.d.ts +10 -0
- package/dist/content/form-error.d.ts.map +1 -0
- package/dist/content/form-error.js +2 -0
- package/dist/content/form-error.js.map +1 -0
- package/dist/{web → content}/guids.d.ts +12 -5
- package/dist/content/guids.d.ts.map +1 -0
- package/dist/{web → content}/guids.js +28 -5
- package/dist/content/guids.js.map +1 -0
- package/dist/content/image-tags.d.ts +25 -0
- package/dist/content/image-tags.d.ts.map +1 -0
- package/dist/content/image-tags.js +55 -0
- package/dist/content/image-tags.js.map +1 -0
- package/dist/content/index.d.ts +11 -6
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/index.js +6 -3
- package/dist/content/index.js.map +1 -1
- package/dist/content/kept-properties.d.ts +0 -1
- package/dist/content/kept-properties.d.ts.map +1 -1
- package/dist/content/kept-properties.js +2 -2
- package/dist/content/kept-properties.js.map +1 -1
- package/dist/content/language.d.ts +19 -0
- package/dist/content/language.d.ts.map +1 -0
- package/dist/content/language.js +19 -0
- package/dist/content/language.js.map +1 -0
- package/dist/content/license.d.ts.map +1 -0
- package/dist/content/license.js.map +1 -0
- package/dist/{web → content}/locale.d.ts +0 -6
- package/dist/content/locale.d.ts.map +1 -0
- package/dist/{web → content}/locale.js +1 -6
- package/dist/content/locale.js.map +1 -0
- package/dist/content/location-form.d.ts +17 -0
- package/dist/content/location-form.d.ts.map +1 -0
- package/dist/{admin/location-field.js → content/location-form.js} +2 -23
- package/dist/content/location-form.js.map +1 -0
- package/dist/content/location.d.ts.map +1 -1
- package/dist/content/location.js +1 -3
- package/dist/content/location.js.map +1 -1
- package/dist/content/locations.d.ts +0 -1
- package/dist/content/locations.d.ts.map +1 -1
- package/dist/content/locations.js +2 -2
- package/dist/content/locations.js.map +1 -1
- package/dist/content/markdown-links.d.ts +11 -0
- package/dist/content/markdown-links.d.ts.map +1 -0
- package/dist/content/markdown-links.js +223 -0
- package/dist/content/markdown-links.js.map +1 -0
- package/dist/content/markdown.d.ts +2 -1
- package/dist/content/markdown.d.ts.map +1 -1
- package/dist/content/markdown.js +1 -1
- package/dist/content/markdown.js.map +1 -1
- package/dist/content/media.d.ts +7 -0
- package/dist/content/media.d.ts.map +1 -1
- package/dist/content/media.js +12 -1
- package/dist/content/media.js.map +1 -1
- package/dist/content/metadata/strip-job.d.ts +16 -0
- package/dist/content/metadata/strip-job.d.ts.map +1 -0
- package/dist/content/metadata/strip-job.js +24 -0
- package/dist/content/metadata/strip-job.js.map +1 -0
- package/dist/content/metadata/sweep.d.ts +13 -1
- package/dist/content/metadata/sweep.d.ts.map +1 -1
- package/dist/content/metadata/sweep.js +47 -25
- package/dist/content/metadata/sweep.js.map +1 -1
- package/dist/content/migrated.js +1 -1
- package/dist/content/migrated.js.map +1 -1
- package/dist/content/parser.d.ts.map +1 -1
- package/dist/content/parser.js +1 -12
- package/dist/content/parser.js.map +1 -1
- package/dist/content/permalink-file.d.ts +2 -1
- package/dist/content/permalink-file.d.ts.map +1 -1
- package/dist/content/permalink-file.js +3 -3
- package/dist/content/permalink-file.js.map +1 -1
- package/dist/content/permalinks.d.ts +34 -0
- package/dist/content/permalinks.d.ts.map +1 -0
- package/dist/{web/documents.js → content/permalinks.js} +6 -56
- package/dist/content/permalinks.js.map +1 -0
- package/dist/content/photo-form.d.ts +29 -0
- package/dist/content/photo-form.d.ts.map +1 -0
- package/dist/{admin/photo-field.js → content/photo-form.js} +43 -40
- package/dist/content/photo-form.js.map +1 -0
- package/dist/content/photo.d.ts +2 -1
- package/dist/content/photo.d.ts.map +1 -1
- package/dist/content/photo.js +2 -2
- package/dist/content/photo.js.map +1 -1
- package/dist/content/post-fields.d.ts +40 -0
- package/dist/content/post-fields.d.ts.map +1 -0
- package/dist/content/post-fields.js +252 -0
- package/dist/content/post-fields.js.map +1 -0
- package/dist/content/read-form.d.ts +31 -0
- package/dist/content/read-form.d.ts.map +1 -0
- package/dist/content/read-form.js +157 -0
- package/dist/content/read-form.js.map +1 -0
- package/dist/content/read.d.ts +9 -2
- package/dist/content/read.d.ts.map +1 -1
- package/dist/content/read.js +28 -13
- package/dist/content/read.js.map +1 -1
- package/dist/content/redirects.d.ts +84 -0
- package/dist/content/redirects.d.ts.map +1 -0
- package/dist/content/redirects.js +234 -0
- package/dist/content/redirects.js.map +1 -0
- package/dist/content/sanitize.d.ts +13 -0
- package/dist/content/sanitize.d.ts.map +1 -0
- package/dist/{web → content}/sanitize.js +4 -71
- package/dist/content/sanitize.js.map +1 -0
- package/dist/content/save.d.ts +5 -8
- package/dist/content/save.d.ts.map +1 -1
- package/dist/content/save.js +5 -26
- package/dist/content/save.js.map +1 -1
- package/dist/content/schedule.d.ts +2 -2
- package/dist/content/schedule.d.ts.map +1 -1
- package/dist/content/schedule.js +1 -3
- package/dist/content/schedule.js.map +1 -1
- package/dist/content/served.d.ts +58 -0
- package/dist/content/served.d.ts.map +1 -0
- package/dist/content/served.js +65 -0
- package/dist/content/served.js.map +1 -0
- package/dist/content/site-links.d.ts +72 -0
- package/dist/content/site-links.d.ts.map +1 -0
- package/dist/content/site-links.js +191 -0
- package/dist/content/site-links.js.map +1 -0
- package/dist/content/sqlite/archive.d.ts +4 -0
- package/dist/content/sqlite/archive.d.ts.map +1 -0
- package/dist/content/sqlite/archive.js +96 -0
- package/dist/content/sqlite/archive.js.map +1 -0
- package/dist/content/sqlite/backlinks.d.ts +4 -0
- package/dist/content/sqlite/backlinks.d.ts.map +1 -0
- package/dist/content/sqlite/backlinks.js +46 -0
- package/dist/content/sqlite/backlinks.js.map +1 -0
- package/dist/content/sqlite/catalog.d.ts +4 -0
- package/dist/content/sqlite/catalog.d.ts.map +1 -0
- package/dist/content/sqlite/catalog.js +62 -0
- package/dist/content/sqlite/catalog.js.map +1 -0
- package/dist/content/sqlite/clauses.d.ts +57 -0
- package/dist/content/sqlite/clauses.d.ts.map +1 -0
- package/dist/content/sqlite/clauses.js +76 -0
- package/dist/content/sqlite/clauses.js.map +1 -0
- package/dist/content/sqlite/database.d.ts +26 -0
- package/dist/content/sqlite/database.d.ts.map +1 -0
- package/dist/content/sqlite/database.js +27 -0
- package/dist/content/sqlite/database.js.map +1 -0
- package/dist/content/sqlite/documents.d.ts +12 -0
- package/dist/content/sqlite/documents.d.ts.map +1 -0
- package/dist/content/sqlite/documents.js +40 -0
- package/dist/content/sqlite/documents.js.map +1 -0
- package/dist/content/sqlite/lookups.d.ts +6 -0
- package/dist/content/sqlite/lookups.d.ts.map +1 -0
- package/dist/content/sqlite/lookups.js +25 -0
- package/dist/content/sqlite/lookups.js.map +1 -0
- package/dist/content/sqlite/open.d.ts +8 -0
- package/dist/content/sqlite/open.d.ts.map +1 -0
- package/dist/content/sqlite/open.js +63 -0
- package/dist/content/sqlite/open.js.map +1 -0
- package/dist/content/sqlite/replies.d.ts +4 -0
- package/dist/content/sqlite/replies.d.ts.map +1 -0
- package/dist/content/sqlite/replies.js +21 -0
- package/dist/content/sqlite/replies.js.map +1 -0
- package/dist/content/sqlite/rows.d.ts +22 -0
- package/dist/content/sqlite/rows.d.ts.map +1 -0
- package/dist/content/sqlite/rows.js +93 -0
- package/dist/content/sqlite/rows.js.map +1 -0
- package/dist/content/sqlite/schedule.d.ts +4 -0
- package/dist/content/sqlite/schedule.d.ts.map +1 -0
- package/dist/content/sqlite/schedule.js +16 -0
- package/dist/content/sqlite/schedule.js.map +1 -0
- package/dist/content/sqlite/schema.d.ts +10 -0
- package/dist/content/sqlite/schema.d.ts.map +1 -0
- package/dist/content/sqlite/schema.js +209 -0
- package/dist/content/sqlite/schema.js.map +1 -0
- package/dist/content/sqlite/search.d.ts +4 -0
- package/dist/content/sqlite/search.d.ts.map +1 -0
- package/dist/content/sqlite/search.js +54 -0
- package/dist/content/sqlite/search.js.map +1 -0
- package/dist/content/sqlite/spellings.d.ts +6 -0
- package/dist/content/sqlite/spellings.d.ts.map +1 -0
- package/dist/content/sqlite/spellings.js +80 -0
- package/dist/content/sqlite/spellings.js.map +1 -0
- package/dist/content/sqlite/taxonomy.d.ts +4 -0
- package/dist/content/sqlite/taxonomy.d.ts.map +1 -0
- package/dist/content/sqlite/taxonomy.js +75 -0
- package/dist/content/sqlite/taxonomy.js.map +1 -0
- package/dist/content/sqlite/writes.d.ts +9 -0
- package/dist/content/sqlite/writes.d.ts.map +1 -0
- package/dist/content/sqlite/writes.js +164 -0
- package/dist/content/sqlite/writes.js.map +1 -0
- package/dist/content/store.d.ts +142 -138
- package/dist/content/store.d.ts.map +1 -1
- package/dist/content/store.js +0 -1051
- package/dist/content/store.js.map +1 -1
- package/dist/content/sync.d.ts +12 -4
- package/dist/content/sync.d.ts.map +1 -1
- package/dist/content/sync.js +24 -41
- package/dist/content/sync.js.map +1 -1
- package/dist/content/syndicate-to.d.ts +25 -0
- package/dist/content/syndicate-to.d.ts.map +1 -0
- package/dist/content/syndicate-to.js +8 -0
- package/dist/content/syndicate-to.js.map +1 -0
- package/dist/{web → content}/taxonomy.d.ts +1 -1
- package/dist/content/taxonomy.d.ts.map +1 -0
- package/dist/{web → content}/taxonomy.js +2 -2
- package/dist/content/taxonomy.js.map +1 -0
- package/dist/content/time.d.ts +2 -2
- package/dist/content/time.d.ts.map +1 -1
- package/dist/content/time.js +3 -3
- package/dist/content/time.js.map +1 -1
- package/dist/content/trash.d.ts +35 -0
- package/dist/content/trash.d.ts.map +1 -0
- package/dist/content/trash.js +83 -0
- package/dist/content/trash.js.map +1 -0
- package/dist/content/uploads.d.ts +24 -0
- package/dist/content/uploads.d.ts.map +1 -0
- package/dist/content/uploads.js +32 -0
- package/dist/content/uploads.js.map +1 -0
- package/dist/content/video.d.ts.map +1 -1
- package/dist/content/video.js +3 -5
- package/dist/content/video.js.map +1 -1
- package/dist/content/write.d.ts +84 -0
- package/dist/content/write.d.ts.map +1 -0
- package/dist/content/write.js +570 -0
- package/dist/content/write.js.map +1 -0
- package/dist/content/writer.d.ts.map +1 -1
- package/dist/content/writer.js +1 -2
- package/dist/content/writer.js.map +1 -1
- package/dist/dev-mode.d.ts +6 -26
- package/dist/dev-mode.d.ts.map +1 -1
- package/dist/dev-mode.js +5 -54
- package/dist/dev-mode.js.map +1 -1
- package/dist/drain.d.ts +2 -3
- package/dist/drain.d.ts.map +1 -1
- package/dist/drain.js +2 -1
- package/dist/drain.js.map +1 -1
- package/dist/export/export-archives.d.ts +29 -0
- package/dist/export/export-archives.d.ts.map +1 -0
- package/dist/export/export-archives.js +88 -0
- package/dist/export/export-archives.js.map +1 -0
- package/dist/export/export-job.d.ts +21 -0
- package/dist/export/export-job.d.ts.map +1 -0
- package/dist/export/export-job.js +63 -0
- package/dist/export/export-job.js.map +1 -0
- package/dist/export/site-export.d.ts +101 -0
- package/dist/export/site-export.d.ts.map +1 -0
- package/dist/export/site-export.js +243 -0
- package/dist/export/site-export.js.map +1 -0
- package/dist/export/site-import.d.ts +75 -0
- package/dist/export/site-import.d.ts.map +1 -0
- package/dist/export/site-import.js +492 -0
- package/dist/export/site-import.js.map +1 -0
- package/dist/exports.d.ts +31 -0
- package/dist/exports.d.ts.map +1 -0
- package/dist/exports.js +10 -0
- package/dist/exports.js.map +1 -0
- package/dist/federation/actor.d.ts +1 -1
- package/dist/federation/actor.d.ts.map +1 -1
- package/dist/federation/actor.js +6 -13
- package/dist/federation/actor.js.map +1 -1
- package/dist/federation/article.d.ts +4 -14
- package/dist/federation/article.d.ts.map +1 -1
- package/dist/federation/article.js +40 -51
- package/dist/federation/article.js.map +1 -1
- package/dist/federation/backfill.d.ts +7 -5
- package/dist/federation/backfill.d.ts.map +1 -1
- package/dist/federation/backfill.js +12 -13
- package/dist/federation/backfill.js.map +1 -1
- package/dist/federation/citations.d.ts.map +1 -1
- package/dist/federation/citations.js.map +1 -1
- package/dist/federation/cited-post.d.ts +1 -1
- package/dist/federation/cited-post.d.ts.map +1 -1
- package/dist/federation/cited-post.js +3 -5
- package/dist/federation/cited-post.js.map +1 -1
- package/dist/federation/delivery-plan.d.ts +85 -0
- package/dist/federation/delivery-plan.d.ts.map +1 -0
- package/dist/federation/delivery-plan.js +137 -0
- package/dist/federation/delivery-plan.js.map +1 -0
- package/dist/federation/delivery.d.ts +12 -34
- package/dist/federation/delivery.d.ts.map +1 -1
- package/dist/federation/delivery.js +79 -212
- package/dist/federation/delivery.js.map +1 -1
- package/dist/federation/federation.d.ts +12 -12
- package/dist/federation/federation.d.ts.map +1 -1
- package/dist/federation/federation.js +12 -18
- package/dist/federation/federation.js.map +1 -1
- package/dist/federation/followers.d.ts +1 -1
- package/dist/federation/followers.d.ts.map +1 -1
- package/dist/federation/handles.d.ts +1 -1
- package/dist/federation/handles.d.ts.map +1 -1
- package/dist/federation/handles.js +1 -1
- package/dist/federation/handles.js.map +1 -1
- package/dist/federation/inbox.d.ts +1 -1
- package/dist/federation/inbox.d.ts.map +1 -1
- package/dist/federation/inbox.js +6 -5
- package/dist/federation/inbox.js.map +1 -1
- package/dist/federation/index.d.ts +10 -8
- package/dist/federation/index.d.ts.map +1 -1
- package/dist/federation/index.js +7 -5
- package/dist/federation/index.js.map +1 -1
- package/dist/federation/keys.d.ts +8 -27
- package/dist/federation/keys.d.ts.map +1 -1
- package/dist/federation/keys.js +7 -50
- package/dist/federation/keys.js.map +1 -1
- package/dist/federation/mount.d.ts +2 -2
- package/dist/federation/mount.d.ts.map +1 -1
- package/dist/federation/mount.js +9 -7
- package/dist/federation/mount.js.map +1 -1
- package/dist/federation/paths.d.ts +1 -9
- package/dist/federation/paths.d.ts.map +1 -1
- package/dist/federation/paths.js +2 -12
- package/dist/federation/paths.js.map +1 -1
- package/dist/federation/profiles.d.ts +2 -2
- package/dist/federation/profiles.d.ts.map +1 -1
- package/dist/federation/profiles.js +6 -9
- package/dist/federation/profiles.js.map +1 -1
- package/dist/federation/queue.d.ts +32 -17
- package/dist/federation/queue.d.ts.map +1 -1
- package/dist/federation/queue.js +173 -39
- package/dist/federation/queue.js.map +1 -1
- package/dist/federation/quotes.d.ts +2 -2
- package/dist/federation/quotes.d.ts.map +1 -1
- package/dist/federation/quotes.js +4 -4
- package/dist/federation/quotes.js.map +1 -1
- package/dist/federation/records.d.ts +2 -2
- package/dist/federation/records.d.ts.map +1 -1
- package/dist/federation/records.js +12 -19
- package/dist/federation/records.js.map +1 -1
- package/dist/federation/relays.d.ts +8 -5
- package/dist/federation/relays.d.ts.map +1 -1
- package/dist/federation/relays.js +52 -53
- package/dist/federation/relays.js.map +1 -1
- package/dist/federation/resend-job.d.ts +44 -0
- package/dist/federation/resend-job.d.ts.map +1 -0
- package/dist/federation/resend-job.js +59 -0
- package/dist/federation/resend-job.js.map +1 -0
- package/dist/federation/site-loaders.js +1 -1
- package/dist/federation/site-loaders.js.map +1 -1
- package/dist/federation/webfinger.d.ts +23 -0
- package/dist/federation/webfinger.d.ts.map +1 -0
- package/dist/federation/webfinger.js +70 -0
- package/dist/federation/webfinger.js.map +1 -0
- package/dist/files/atomic.d.ts +9 -0
- package/dist/files/atomic.d.ts.map +1 -1
- package/dist/files/atomic.js +5 -10
- package/dist/files/atomic.js.map +1 -1
- package/dist/files/data-files.d.ts +104 -0
- package/dist/files/data-files.d.ts.map +1 -0
- package/dist/files/data-files.js +330 -0
- package/dist/files/data-files.js.map +1 -0
- package/dist/files/export-archives.d.ts +12 -0
- package/dist/files/export-archives.d.ts.map +1 -0
- package/dist/files/export-archives.js +67 -0
- package/dist/files/export-archives.js.map +1 -0
- package/dist/files/static-files.d.ts +21 -0
- package/dist/files/static-files.d.ts.map +1 -0
- package/dist/files/static-files.js +73 -0
- package/dist/files/static-files.js.map +1 -0
- package/dist/files/tar.d.ts +29 -0
- package/dist/files/tar.d.ts.map +1 -0
- package/dist/files/tar.js +206 -0
- package/dist/files/tar.js.map +1 -0
- package/dist/files/upload-types.d.ts +81 -0
- package/dist/files/upload-types.d.ts.map +1 -0
- package/dist/files/upload-types.js +234 -0
- package/dist/files/upload-types.js.map +1 -0
- package/dist/forms/checker.d.ts +93 -0
- package/dist/forms/checker.d.ts.map +1 -0
- package/dist/forms/checker.js +2 -0
- package/dist/forms/checker.js.map +1 -0
- package/dist/forms/protection.d.ts +3 -9
- package/dist/forms/protection.d.ts.map +1 -1
- package/dist/forms/protection.js +5 -11
- package/dist/forms/protection.js.map +1 -1
- package/dist/images/icons.d.ts.map +1 -1
- package/dist/images/icons.js +4 -2
- package/dist/images/icons.js.map +1 -1
- package/dist/images/index.d.ts +2 -1
- package/dist/images/index.d.ts.map +1 -1
- package/dist/images/index.js +2 -1
- package/dist/images/index.js.map +1 -1
- package/dist/images/markup.d.ts +4 -21
- package/dist/images/markup.d.ts.map +1 -1
- package/dist/images/markup.js +15 -70
- package/dist/images/markup.js.map +1 -1
- package/dist/images/paths.d.ts +1 -14
- package/dist/images/paths.d.ts.map +1 -1
- package/dist/images/paths.js +9 -23
- package/dist/images/paths.js.map +1 -1
- package/dist/images/variants.d.ts +5 -3
- package/dist/images/variants.d.ts.map +1 -1
- package/dist/images/variants.js +23 -22
- package/dist/images/variants.js.map +1 -1
- package/dist/index.d.ts +4 -291
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -839
- package/dist/index.js.map +1 -1
- package/dist/indexnow.d.ts +4 -2
- package/dist/indexnow.d.ts.map +1 -1
- package/dist/indexnow.js +52 -45
- package/dist/indexnow.js.map +1 -1
- package/dist/indieauth/client.d.ts +1 -1
- package/dist/indieauth/client.d.ts.map +1 -1
- package/dist/indieauth/client.js +1 -1
- package/dist/indieauth/client.js.map +1 -1
- package/dist/indieauth/grants.d.ts +1 -1
- package/dist/indieauth/grants.d.ts.map +1 -1
- package/dist/indieauth/identity.d.ts +2 -2
- package/dist/indieauth/identity.d.ts.map +1 -1
- package/dist/indieauth/identity.js +5 -7
- package/dist/indieauth/identity.js.map +1 -1
- package/dist/indieauth/redeem.d.ts +1 -1
- package/dist/indieauth/redeem.d.ts.map +1 -1
- package/dist/indieauth/redeem.js.map +1 -1
- package/dist/indieauth/request.d.ts +5 -1
- package/dist/indieauth/request.d.ts.map +1 -1
- package/dist/indieauth/request.js +6 -2
- package/dist/indieauth/request.js.map +1 -1
- package/dist/indieauth/tokens.d.ts +1 -3
- package/dist/indieauth/tokens.d.ts.map +1 -1
- package/dist/indieauth/tokens.js +4 -6
- package/dist/indieauth/tokens.js.map +1 -1
- package/dist/jobs/file-records.d.ts +13 -0
- package/dist/jobs/file-records.d.ts.map +1 -0
- package/dist/jobs/file-records.js +104 -0
- package/dist/jobs/file-records.js.map +1 -0
- package/dist/jobs/in-process.d.ts +10 -0
- package/dist/jobs/in-process.d.ts.map +1 -0
- package/dist/jobs/in-process.js +45 -0
- package/dist/jobs/in-process.js.map +1 -0
- package/dist/jobs/lock-file.d.ts +13 -0
- package/dist/jobs/lock-file.d.ts.map +1 -0
- package/dist/jobs/lock-file.js +107 -0
- package/dist/jobs/lock-file.js.map +1 -0
- package/dist/jobs/processes.d.ts +11 -0
- package/dist/jobs/processes.d.ts.map +1 -0
- package/dist/jobs/processes.js +50 -0
- package/dist/jobs/processes.js.map +1 -0
- package/dist/jobs/queue.d.ts +18 -0
- package/dist/jobs/queue.d.ts.map +1 -0
- package/dist/jobs/queue.js +220 -0
- package/dist/jobs/queue.js.map +1 -0
- package/dist/jobs/types.d.ts +159 -0
- package/dist/jobs/types.d.ts.map +1 -0
- package/dist/jobs/types.js +22 -0
- package/dist/jobs/types.js.map +1 -0
- package/dist/mail/index.d.ts +1 -7
- package/dist/mail/index.d.ts.map +1 -1
- package/dist/mail/index.js +0 -3
- package/dist/mail/index.js.map +1 -1
- package/dist/mail/provider.d.ts +7 -0
- package/dist/mail/provider.d.ts.map +1 -1
- package/dist/maintenance.d.ts +6 -43
- package/dist/maintenance.d.ts.map +1 -1
- package/dist/maintenance.js +4 -67
- package/dist/maintenance.js.map +1 -1
- package/dist/media/library.d.ts +99 -0
- package/dist/media/library.d.ts.map +1 -0
- package/dist/media/library.js +160 -0
- package/dist/media/library.js.map +1 -0
- package/dist/media/uploads.d.ts +106 -0
- package/dist/media/uploads.d.ts.map +1 -0
- package/dist/media/uploads.js +192 -0
- package/dist/media/uploads.js.map +1 -0
- package/dist/micropub/content.js +1 -1
- package/dist/micropub/content.js.map +1 -1
- package/dist/micropub/create.d.ts +7 -15
- package/dist/micropub/create.d.ts.map +1 -1
- package/dist/micropub/create.js +48 -184
- package/dist/micropub/create.js.map +1 -1
- package/dist/micropub/endpoint.d.ts +2 -2
- package/dist/micropub/endpoint.d.ts.map +1 -1
- package/dist/micropub/endpoint.js +36 -47
- package/dist/micropub/endpoint.js.map +1 -1
- package/dist/micropub/media.d.ts +1 -3
- package/dist/micropub/media.d.ts.map +1 -1
- package/dist/micropub/media.js +10 -12
- package/dist/micropub/media.js.map +1 -1
- package/dist/micropub/update.d.ts +6 -14
- package/dist/micropub/update.d.ts.map +1 -1
- package/dist/micropub/update.js +37 -90
- package/dist/micropub/update.js.map +1 -1
- package/dist/notifications/comments.d.ts +8 -6
- package/dist/notifications/comments.d.ts.map +1 -1
- package/dist/notifications/comments.js +80 -76
- package/dist/notifications/comments.js.map +1 -1
- package/dist/notifications/digest.d.ts +6 -8
- package/dist/notifications/digest.d.ts.map +1 -1
- package/dist/notifications/digest.js +15 -26
- package/dist/notifications/digest.js.map +1 -1
- package/dist/notifications/index.d.ts +9 -6
- package/dist/notifications/index.d.ts.map +1 -1
- package/dist/notifications/index.js +6 -5
- package/dist/notifications/index.js.map +1 -1
- package/dist/notifications/links.d.ts.map +1 -1
- package/dist/notifications/links.js +2 -2
- package/dist/notifications/links.js.map +1 -1
- package/dist/{mail/service.d.ts → notifications/mail-service.d.ts} +16 -20
- package/dist/notifications/mail-service.d.ts.map +1 -0
- package/dist/{mail/service.js → notifications/mail-service.js} +100 -121
- package/dist/notifications/mail-service.js.map +1 -0
- package/dist/{mail/templates.d.ts → notifications/mail-templates.d.ts} +4 -2
- package/dist/notifications/mail-templates.d.ts.map +1 -0
- package/dist/{mail/templates.js → notifications/mail-templates.js} +5 -3
- package/dist/notifications/mail-templates.js.map +1 -0
- package/dist/notifications/optouts.d.ts +0 -2
- package/dist/notifications/optouts.d.ts.map +1 -1
- package/dist/notifications/optouts.js +2 -4
- package/dist/notifications/optouts.js.map +1 -1
- package/dist/notifications/tokens.d.ts +2 -4
- package/dist/notifications/tokens.d.ts.map +1 -1
- package/dist/notifications/tokens.js +4 -30
- package/dist/notifications/tokens.js.map +1 -1
- package/dist/notify.d.ts +4 -2
- package/dist/notify.d.ts.map +1 -1
- package/dist/notify.js +35 -35
- package/dist/notify.js.map +1 -1
- package/dist/plugin.d.ts +59 -19
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +22 -4
- package/dist/plugin.js.map +1 -1
- package/dist/plugins/changes.d.ts +0 -1
- package/dist/plugins/changes.d.ts.map +1 -1
- package/dist/plugins/changes.js +2 -3
- package/dist/plugins/changes.js.map +1 -1
- package/dist/plugins/data.d.ts +19 -0
- package/dist/plugins/data.d.ts.map +1 -0
- package/dist/plugins/data.js +117 -0
- package/dist/plugins/data.js.map +1 -0
- package/dist/plugins/enabled.d.ts +1 -13
- package/dist/plugins/enabled.d.ts.map +1 -1
- package/dist/plugins/enabled.js +12 -26
- package/dist/plugins/enabled.js.map +1 -1
- package/dist/plugins/fetch.d.ts +1 -1
- package/dist/plugins/fetch.d.ts.map +1 -1
- package/dist/plugins/fetch.js +1 -1
- package/dist/plugins/fetch.js.map +1 -1
- package/dist/plugins/folder.d.ts.map +1 -1
- package/dist/plugins/folder.js +1 -3
- package/dist/plugins/folder.js.map +1 -1
- package/dist/plugins/install.d.ts +1 -1
- package/dist/plugins/install.d.ts.map +1 -1
- package/dist/plugins/install.js +14 -45
- package/dist/plugins/install.js.map +1 -1
- package/dist/plugins/manage.d.ts +1 -1
- package/dist/plugins/manage.d.ts.map +1 -1
- package/dist/plugins/migrate-settings.d.ts +7 -0
- package/dist/plugins/migrate-settings.d.ts.map +1 -0
- package/dist/plugins/migrate-settings.js +41 -0
- package/dist/plugins/migrate-settings.js.map +1 -0
- package/dist/plugins/registry.d.ts +10 -14
- package/dist/plugins/registry.d.ts.map +1 -1
- package/dist/plugins/registry.js +63 -45
- package/dist/plugins/registry.js.map +1 -1
- package/dist/plugins/settings.d.ts +5 -57
- package/dist/plugins/settings.d.ts.map +1 -1
- package/dist/plugins/settings.js +47 -181
- package/dist/plugins/settings.js.map +1 -1
- package/dist/plugins/site.d.ts +3 -2
- package/dist/plugins/site.d.ts.map +1 -1
- package/dist/plugins/site.js +8 -8
- package/dist/plugins/site.js.map +1 -1
- package/dist/plugins/upgrade.d.ts.map +1 -1
- package/dist/plugins/upgrade.js +4 -3
- package/dist/plugins/upgrade.js.map +1 -1
- package/dist/privacy/erase.d.ts +1 -1
- package/dist/privacy/erase.d.ts.map +1 -1
- package/dist/privacy/retention.d.ts +6 -2
- package/dist/privacy/retention.d.ts.map +1 -1
- package/dist/privacy/retention.js +20 -15
- package/dist/privacy/retention.js.map +1 -1
- package/dist/settings/akismet.d.ts +9 -0
- package/dist/settings/akismet.d.ts.map +1 -0
- package/dist/settings/akismet.js +46 -0
- package/dist/settings/akismet.js.map +1 -0
- package/dist/settings/declare.d.ts +15 -0
- package/dist/settings/declare.d.ts.map +1 -0
- package/dist/settings/declare.js +20 -0
- package/dist/settings/declare.js.map +1 -0
- package/dist/settings/dev-mode.d.ts +29 -0
- package/dist/settings/dev-mode.d.ts.map +1 -0
- package/dist/settings/dev-mode.js +77 -0
- package/dist/settings/dev-mode.js.map +1 -0
- package/dist/settings/kinds.d.ts +13 -0
- package/dist/settings/kinds.d.ts.map +1 -0
- package/dist/settings/kinds.js +108 -0
- package/dist/settings/kinds.js.map +1 -0
- package/dist/settings/mail.d.ts +10 -0
- package/dist/settings/mail.d.ts.map +1 -0
- package/dist/settings/mail.js +92 -0
- package/dist/settings/mail.js.map +1 -0
- package/dist/settings/maintenance.d.ts +6 -0
- package/dist/settings/maintenance.d.ts.map +1 -0
- package/dist/settings/maintenance.js +33 -0
- package/dist/settings/maintenance.js.map +1 -0
- package/dist/settings/names.d.ts +7 -0
- package/dist/settings/names.d.ts.map +1 -0
- package/dist/settings/names.js +31 -0
- package/dist/settings/names.js.map +1 -0
- package/dist/settings/presence.d.ts +2 -0
- package/dist/settings/presence.d.ts.map +1 -0
- package/dist/settings/presence.js +7 -0
- package/dist/settings/presence.js.map +1 -0
- package/dist/settings/registry.d.ts +14 -0
- package/dist/settings/registry.d.ts.map +1 -0
- package/dist/settings/registry.js +369 -0
- package/dist/settings/registry.js.map +1 -0
- package/dist/settings/types.d.ts +176 -0
- package/dist/settings/types.d.ts.map +1 -0
- package/dist/settings/types.js +2 -0
- package/dist/settings/types.js.map +1 -0
- package/dist/site/admin-paths.d.ts +23 -0
- package/dist/site/admin-paths.d.ts.map +1 -0
- package/dist/site/admin-paths.js +25 -0
- package/dist/site/admin-paths.js.map +1 -0
- package/dist/site/admin-theme.d.ts.map +1 -0
- package/dist/site/admin-theme.js.map +1 -0
- package/dist/{web → site}/authors.d.ts +1 -72
- package/dist/site/authors.d.ts.map +1 -0
- package/dist/site/authors.js +107 -0
- package/dist/site/authors.js.map +1 -0
- package/dist/site/feed-settings.d.ts +28 -0
- package/dist/site/feed-settings.d.ts.map +1 -0
- package/dist/site/feed-settings.js +22 -0
- package/dist/site/feed-settings.js.map +1 -0
- package/dist/{web/indexnow.d.ts → site/indexnow-key.d.ts} +1 -1
- package/dist/site/indexnow-key.d.ts.map +1 -0
- package/dist/{web/indexnow.js → site/indexnow-key.js} +1 -1
- package/dist/site/indexnow-key.js.map +1 -0
- package/dist/site/namespace.d.ts +88 -0
- package/dist/site/namespace.d.ts.map +1 -0
- package/dist/site/namespace.js +471 -0
- package/dist/site/namespace.js.map +1 -0
- package/dist/{web → site}/navigation.d.ts +7 -1
- package/dist/site/navigation.d.ts.map +1 -0
- package/dist/{web → site}/navigation.js +18 -0
- package/dist/site/navigation.js.map +1 -0
- package/dist/{notifications/preferences.d.ts → site/notification-preferences.d.ts} +2 -2
- package/dist/site/notification-preferences.d.ts.map +1 -0
- package/dist/{notifications/preferences.js → site/notification-preferences.js} +1 -1
- package/dist/site/notification-preferences.js.map +1 -0
- package/dist/site/passwords.d.ts.map +1 -0
- package/dist/site/passwords.js.map +1 -0
- package/dist/{privacy/policy.d.ts → site/retention-policy.d.ts} +1 -1
- package/dist/site/retention-policy.d.ts.map +1 -0
- package/dist/{privacy/policy.js → site/retention-policy.js} +1 -1
- package/dist/site/retention-policy.js.map +1 -0
- package/dist/site/robots.d.ts +62 -0
- package/dist/site/robots.d.ts.map +1 -0
- package/dist/site/robots.js +130 -0
- package/dist/site/robots.js.map +1 -0
- package/dist/site/setting-rows.d.ts +45 -0
- package/dist/site/setting-rows.d.ts.map +1 -0
- package/dist/site/setting-rows.js +361 -0
- package/dist/site/setting-rows.js.map +1 -0
- package/dist/site/setting-values.d.ts +63 -0
- package/dist/site/setting-values.d.ts.map +1 -0
- package/dist/site/setting-values.js +170 -0
- package/dist/site/setting-values.js.map +1 -0
- package/dist/site/settings-form.d.ts +30 -0
- package/dist/site/settings-form.d.ts.map +1 -0
- package/dist/site/settings-form.js +54 -0
- package/dist/site/settings-form.js.map +1 -0
- package/dist/site/settings.d.ts +29 -0
- package/dist/site/settings.d.ts.map +1 -0
- package/dist/site/settings.js +44 -0
- package/dist/site/settings.js.map +1 -0
- package/dist/site/site-json.d.ts +38 -0
- package/dist/site/site-json.d.ts.map +1 -0
- package/dist/site/site-json.js +69 -0
- package/dist/site/site-json.js.map +1 -0
- package/dist/{admin/accounts.d.ts → site/users.d.ts} +25 -50
- package/dist/site/users.d.ts.map +1 -0
- package/dist/{admin/accounts.js → site/users.js} +51 -166
- package/dist/site/users.js.map +1 -0
- package/dist/store/admin-store.d.ts +72 -0
- package/dist/store/admin-store.d.ts.map +1 -0
- package/dist/store/admin-store.js +62 -0
- package/dist/store/admin-store.js.map +1 -0
- package/dist/store/comments.d.ts +253 -0
- package/dist/store/comments.d.ts.map +1 -0
- package/dist/store/comments.js +234 -0
- package/dist/store/comments.js.map +1 -0
- package/dist/store/conversation.d.ts +28 -0
- package/dist/store/conversation.d.ts.map +1 -0
- package/dist/store/conversation.js +16 -0
- package/dist/store/conversation.js.map +1 -0
- package/dist/store/deliveries.d.ts +92 -0
- package/dist/store/deliveries.d.ts.map +1 -0
- package/dist/store/deliveries.js +88 -0
- package/dist/store/deliveries.js.map +1 -0
- package/dist/store/followers.d.ts +91 -0
- package/dist/store/followers.d.ts.map +1 -0
- package/dist/store/followers.js +79 -0
- package/dist/store/followers.js.map +1 -0
- package/dist/{federation/replies.d.ts → store/inbox-replies.d.ts} +2 -2
- package/dist/store/inbox-replies.d.ts.map +1 -0
- package/dist/{federation/replies.js → store/inbox-replies.js} +2 -4
- package/dist/store/inbox-replies.js.map +1 -0
- package/dist/store/inbox.d.ts +132 -0
- package/dist/store/inbox.d.ts.map +1 -0
- package/dist/store/inbox.js +157 -0
- package/dist/store/inbox.js.map +1 -0
- package/dist/store/profiles.d.ts +49 -0
- package/dist/store/profiles.d.ts.map +1 -0
- package/dist/store/profiles.js +71 -0
- package/dist/store/profiles.js.map +1 -0
- package/dist/store/queue-database.d.ts +11 -0
- package/dist/store/queue-database.d.ts.map +1 -0
- package/dist/store/queue-database.js +39 -0
- package/dist/store/queue-database.js.map +1 -0
- package/dist/store/relays.d.ts +66 -0
- package/dist/store/relays.d.ts.map +1 -0
- package/dist/store/relays.js +69 -0
- package/dist/store/relays.js.map +1 -0
- package/dist/store/rows.d.ts +33 -0
- package/dist/store/rows.d.ts.map +1 -0
- package/dist/store/rows.js +44 -0
- package/dist/store/rows.js.map +1 -0
- package/dist/store/schema.d.ts +14 -0
- package/dist/store/schema.d.ts.map +1 -0
- package/dist/store/schema.js +588 -0
- package/dist/store/schema.js.map +1 -0
- package/dist/store/sessions.d.ts +90 -0
- package/dist/store/sessions.d.ts.map +1 -0
- package/dist/store/sessions.js +107 -0
- package/dist/store/sessions.js.map +1 -0
- package/dist/store/state.d.ts +18 -0
- package/dist/store/state.d.ts.map +1 -0
- package/dist/store/state.js +19 -0
- package/dist/store/state.js.map +1 -0
- package/dist/store/tokens.d.ts +75 -0
- package/dist/store/tokens.d.ts.map +1 -0
- package/dist/store/tokens.js +82 -0
- package/dist/store/tokens.js.map +1 -0
- package/dist/store/webmentions.d.ts +66 -0
- package/dist/store/webmentions.d.ts.map +1 -0
- package/dist/store/webmentions.js +84 -0
- package/dist/store/webmentions.js.map +1 -0
- package/dist/supervisor/control.d.ts +1 -0
- package/dist/supervisor/control.d.ts.map +1 -1
- package/dist/supervisor/control.js +10 -0
- package/dist/supervisor/control.js.map +1 -1
- package/dist/supervisor/primary.d.ts +1 -1
- package/dist/supervisor/primary.d.ts.map +1 -1
- package/dist/supervisor/primary.js +46 -14
- package/dist/supervisor/primary.js.map +1 -1
- package/dist/supervisor/worker.d.ts +6 -2
- package/dist/supervisor/worker.d.ts.map +1 -1
- package/dist/supervisor/worker.js +4 -4
- package/dist/supervisor/worker.js.map +1 -1
- package/dist/testing.d.ts +8 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +6 -0
- package/dist/testing.js.map +1 -0
- package/dist/{web → theme}/assets.d.ts +1 -32
- package/dist/theme/assets.d.ts.map +1 -0
- package/dist/{web → theme}/assets.js +2 -100
- package/dist/theme/assets.js.map +1 -0
- package/dist/theme/site-data.d.ts +187 -0
- package/dist/theme/site-data.d.ts.map +1 -0
- package/dist/theme/site-data.js +160 -0
- package/dist/theme/site-data.js.map +1 -0
- package/dist/{web → theme}/templates.d.ts +2 -0
- package/dist/theme/templates.d.ts.map +1 -0
- package/dist/{web → theme}/templates.js +9 -32
- package/dist/theme/templates.js.map +1 -0
- package/dist/{web → theme}/themes.d.ts +1 -0
- package/dist/theme/themes.d.ts.map +1 -0
- package/dist/{web → theme}/themes.js +6 -3
- package/dist/theme/themes.js.map +1 -0
- package/dist/util/client-id.d.ts.map +1 -0
- package/dist/util/client-id.js.map +1 -0
- package/dist/util/clock.d.ts +9 -0
- package/dist/util/clock.d.ts.map +1 -0
- package/dist/util/clock.js +2 -0
- package/dist/util/clock.js.map +1 -0
- package/dist/util/errors.d.ts +3 -0
- package/dist/util/errors.d.ts.map +1 -0
- package/dist/util/errors.js +5 -0
- package/dist/util/errors.js.map +1 -0
- package/dist/util/files.d.ts +5 -0
- package/dist/util/files.d.ts.map +1 -0
- package/dist/util/files.js +38 -0
- package/dist/util/files.js.map +1 -0
- package/dist/util/forms.d.ts +5 -0
- package/dist/util/forms.d.ts.map +1 -0
- package/dist/util/forms.js +17 -0
- package/dist/util/forms.js.map +1 -0
- package/dist/util/guards.d.ts +4 -0
- package/dist/util/guards.d.ts.map +1 -0
- package/dist/util/guards.js +12 -0
- package/dist/util/guards.js.map +1 -0
- package/dist/{webmention/html.d.ts → util/html-tree.d.ts} +2 -2
- package/dist/util/html-tree.d.ts.map +1 -0
- package/dist/{webmention/html.js → util/html-tree.js} +3 -64
- package/dist/util/html-tree.js.map +1 -0
- package/dist/util/html.d.ts +4 -0
- package/dist/util/html.d.ts.map +1 -0
- package/dist/util/html.js +34 -0
- package/dist/util/html.js.map +1 -0
- package/dist/util/public-address.d.ts.map +1 -0
- package/dist/util/public-address.js.map +1 -0
- package/dist/util/queue.d.ts +7 -0
- package/dist/util/queue.d.ts.map +1 -0
- package/dist/util/queue.js +23 -0
- package/dist/util/queue.js.map +1 -0
- package/dist/util/retry.d.ts +11 -0
- package/dist/util/retry.d.ts.map +1 -0
- package/dist/util/retry.js +14 -0
- package/dist/util/retry.js.map +1 -0
- package/dist/util/url.d.ts +11 -0
- package/dist/util/url.d.ts.map +1 -0
- package/dist/util/url.js +20 -0
- package/dist/util/url.js.map +1 -0
- package/dist/web/absolute-urls.js +1 -1
- package/dist/web/absolute-urls.js.map +1 -1
- package/dist/web/archive.js +2 -2
- package/dist/web/archive.js.map +1 -1
- package/dist/web/asset-routes.d.ts +52 -0
- package/dist/web/asset-routes.d.ts.map +1 -0
- package/dist/web/asset-routes.js +115 -0
- package/dist/web/asset-routes.js.map +1 -0
- package/dist/{avatars/routes.d.ts → web/avatar-routes.d.ts} +2 -2
- package/dist/web/avatar-routes.d.ts.map +1 -0
- package/dist/{avatars/routes.js → web/avatar-routes.js} +3 -3
- package/dist/web/avatar-routes.js.map +1 -0
- package/dist/web/comment-routes.d.ts +18 -0
- package/dist/web/comment-routes.d.ts.map +1 -0
- package/dist/web/comment-routes.js +177 -0
- package/dist/web/comment-routes.js.map +1 -0
- package/dist/web/compression.d.ts.map +1 -1
- package/dist/web/compression.js +1 -2
- package/dist/web/compression.js.map +1 -1
- package/dist/{contact/routes.d.ts → web/contact-routes.d.ts} +2 -2
- package/dist/web/contact-routes.d.ts.map +1 -0
- package/dist/{contact/routes.js → web/contact-routes.js} +15 -18
- package/dist/web/contact-routes.js.map +1 -0
- package/dist/web/context.d.ts +6 -187
- package/dist/web/context.d.ts.map +1 -1
- package/dist/web/context.js +13 -174
- package/dist/web/context.js.map +1 -1
- package/dist/web/conversation.d.ts +6 -357
- package/dist/web/conversation.d.ts.map +1 -1
- package/dist/web/conversation.js +177 -151
- package/dist/web/conversation.js.map +1 -1
- package/dist/web/document-page.d.ts +13 -0
- package/dist/web/document-page.d.ts.map +1 -0
- package/dist/web/document-page.js +137 -0
- package/dist/web/document-page.js.map +1 -0
- package/dist/web/document-site.d.ts +14 -0
- package/dist/web/document-site.d.ts.map +1 -0
- package/dist/web/document-site.js +29 -0
- package/dist/web/document-site.js.map +1 -0
- package/dist/web/embed.d.ts +13 -0
- package/dist/web/embed.d.ts.map +1 -0
- package/dist/web/embed.js +66 -0
- package/dist/web/embed.js.map +1 -0
- package/dist/{env.d.ts → web/env.d.ts} +36 -26
- package/dist/web/env.d.ts.map +1 -0
- package/dist/web/env.js.map +1 -0
- package/dist/web/federation-routes.d.ts +33 -0
- package/dist/web/federation-routes.d.ts.map +1 -0
- package/dist/web/federation-routes.js +282 -0
- package/dist/web/federation-routes.js.map +1 -0
- package/dist/web/feed-atom.d.ts.map +1 -1
- package/dist/web/feed-atom.js +4 -3
- package/dist/web/feed-atom.js.map +1 -1
- package/dist/web/feed-item.d.ts +4 -39
- package/dist/web/feed-item.d.ts.map +1 -1
- package/dist/web/feed-item.js +9 -73
- package/dist/web/feed-item.js.map +1 -1
- package/dist/web/feed-json.js +2 -2
- package/dist/web/feed-json.js.map +1 -1
- package/dist/web/feed-routes.d.ts +35 -0
- package/dist/web/feed-routes.d.ts.map +1 -0
- package/dist/web/feed-routes.js +126 -0
- package/dist/web/feed-routes.js.map +1 -0
- package/dist/web/feed-rss.d.ts.map +1 -1
- package/dist/web/feed-rss.js +9 -6
- package/dist/web/feed-rss.js.map +1 -1
- package/dist/web/feed-source.d.ts +11 -41
- package/dist/web/feed-source.d.ts.map +1 -1
- package/dist/web/feed-source.js +11 -48
- package/dist/web/feed-source.js.map +1 -1
- package/dist/web/feeds.d.ts +4 -2
- package/dist/web/feeds.d.ts.map +1 -1
- package/dist/web/feeds.js +8 -5
- package/dist/web/feeds.js.map +1 -1
- package/dist/web/health.d.ts +1 -1
- package/dist/web/health.d.ts.map +1 -1
- package/dist/web/health.js +1 -1
- package/dist/web/health.js.map +1 -1
- package/dist/web/index.d.ts +53 -29
- package/dist/web/index.d.ts.map +1 -1
- package/dist/web/index.js +37 -18
- package/dist/web/index.js.map +1 -1
- package/dist/{indieauth/activity-log.d.ts → web/indieauth-activity-log.d.ts} +3 -5
- package/dist/web/indieauth-activity-log.d.ts.map +1 -0
- package/dist/{indieauth/activity-log.js → web/indieauth-activity-log.js} +7 -10
- package/dist/web/indieauth-activity-log.js.map +1 -0
- package/dist/{indieauth/bearer.d.ts → web/indieauth-bearer.d.ts} +5 -5
- package/dist/web/indieauth-bearer.d.ts.map +1 -0
- package/dist/{indieauth/bearer.js → web/indieauth-bearer.js} +5 -5
- package/dist/web/indieauth-bearer.js.map +1 -0
- package/dist/{indieauth/discovery.d.ts → web/indieauth-discovery.d.ts} +2 -11
- package/dist/web/indieauth-discovery.d.ts.map +1 -0
- package/dist/{indieauth/discovery.js → web/indieauth-discovery.js} +7 -17
- package/dist/web/indieauth-discovery.js.map +1 -0
- package/dist/{indieauth/token.d.ts → web/indieauth-token.d.ts} +2 -2
- package/dist/web/indieauth-token.d.ts.map +1 -0
- package/dist/{indieauth/token.js → web/indieauth-token.js} +9 -9
- package/dist/web/indieauth-token.js.map +1 -0
- package/dist/web/listing-pages.d.ts +19 -0
- package/dist/web/listing-pages.d.ts.map +1 -0
- package/dist/web/listing-pages.js +147 -0
- package/dist/web/listing-pages.js.map +1 -0
- package/dist/web/listing-subject.d.ts +58 -0
- package/dist/web/listing-subject.d.ts.map +1 -0
- package/dist/web/listing-subject.js +89 -0
- package/dist/web/listing-subject.js.map +1 -0
- package/dist/web/llms.d.ts +16 -15
- package/dist/web/llms.d.ts.map +1 -1
- package/dist/web/llms.js +23 -35
- package/dist/web/llms.js.map +1 -1
- package/dist/web/maintenance.d.ts +1 -1
- package/dist/web/maintenance.d.ts.map +1 -1
- package/dist/web/maintenance.js +10 -16
- package/dist/web/maintenance.js.map +1 -1
- package/dist/web/manifest.d.ts +1 -1
- package/dist/web/manifest.d.ts.map +1 -1
- package/dist/web/manifest.js +2 -1
- package/dist/web/manifest.js.map +1 -1
- package/dist/web/markdown-page.d.ts +76 -0
- package/dist/web/markdown-page.d.ts.map +1 -0
- package/dist/web/markdown-page.js +79 -0
- package/dist/web/markdown-page.js.map +1 -0
- package/dist/web/markdown-representation.d.ts +15 -0
- package/dist/web/markdown-representation.d.ts.map +1 -0
- package/dist/web/markdown-representation.js +130 -0
- package/dist/web/markdown-representation.js.map +1 -0
- package/dist/web/negotiate.d.ts +5 -12
- package/dist/web/negotiate.d.ts.map +1 -1
- package/dist/web/negotiate.js +11 -18
- package/dist/web/negotiate.js.map +1 -1
- package/dist/{notifications/routes.d.ts → web/notification-routes.d.ts} +2 -2
- package/dist/web/notification-routes.d.ts.map +1 -0
- package/dist/{notifications/routes.js → web/notification-routes.js} +24 -29
- package/dist/web/notification-routes.js.map +1 -0
- package/dist/web/oembed.d.ts +2 -2
- package/dist/web/oembed.d.ts.map +1 -1
- package/dist/web/oembed.js +5 -4
- package/dist/web/oembed.js.map +1 -1
- package/dist/web/opensearch.d.ts.map +1 -1
- package/dist/web/opensearch.js +2 -1
- package/dist/web/opensearch.js.map +1 -1
- package/dist/web/page-sources.d.ts +14 -0
- package/dist/web/page-sources.d.ts.map +1 -0
- package/dist/web/page-sources.js +43 -0
- package/dist/web/page-sources.js.map +1 -0
- package/dist/web/pagination.d.ts +1 -0
- package/dist/web/pagination.d.ts.map +1 -1
- package/dist/web/pagination.js +4 -1
- package/dist/web/pagination.js.map +1 -1
- package/dist/web/paths.d.ts +52 -0
- package/dist/web/paths.d.ts.map +1 -0
- package/dist/web/paths.js +208 -0
- package/dist/web/paths.js.map +1 -0
- package/dist/web/pingback-routes.d.ts +5 -0
- package/dist/web/pingback-routes.d.ts.map +1 -0
- package/dist/web/pingback-routes.js +100 -0
- package/dist/web/pingback-routes.js.map +1 -0
- package/dist/{plugins/federation.d.ts → web/plugin-federation.d.ts} +3 -3
- package/dist/web/plugin-federation.d.ts.map +1 -0
- package/dist/{plugins/federation.js → web/plugin-federation.js} +55 -45
- package/dist/web/plugin-federation.js.map +1 -0
- package/dist/{plugins/mount.d.ts → web/plugin-routes.d.ts} +3 -3
- package/dist/web/plugin-routes.d.ts.map +1 -0
- package/dist/{plugins/mount.js → web/plugin-routes.js} +2 -2
- package/dist/web/plugin-routes.js.map +1 -0
- package/dist/web/redirects.d.ts +1 -84
- package/dist/web/redirects.d.ts.map +1 -1
- package/dist/web/redirects.js +0 -232
- package/dist/web/redirects.js.map +1 -1
- package/dist/web/render.d.ts +55 -12
- package/dist/web/render.d.ts.map +1 -1
- package/dist/web/render.js +123 -65
- package/dist/web/render.js.map +1 -1
- package/dist/web/request.d.ts +44 -0
- package/dist/web/request.d.ts.map +1 -0
- package/dist/web/request.js +82 -0
- package/dist/web/request.js.map +1 -0
- package/dist/web/robots.d.ts +1 -46
- package/dist/web/robots.d.ts.map +1 -1
- package/dist/web/robots.js +5 -131
- package/dist/web/robots.js.map +1 -1
- package/dist/web/routes.d.ts +5 -39
- package/dist/web/routes.d.ts.map +1 -1
- package/dist/web/routes.js +102 -1374
- package/dist/web/routes.js.map +1 -1
- package/dist/web/search.d.ts.map +1 -1
- package/dist/web/search.js +2 -9
- package/dist/web/search.js.map +1 -1
- package/dist/{admin → web}/session.d.ts +1 -5
- package/dist/web/session.d.ts.map +1 -0
- package/dist/{admin → web}/session.js +0 -4
- package/dist/web/session.js.map +1 -0
- package/dist/web/share-image.d.ts.map +1 -1
- package/dist/web/share-image.js +3 -2
- package/dist/web/share-image.js.map +1 -1
- package/dist/web/signed-in.d.ts +27 -0
- package/dist/web/signed-in.d.ts.map +1 -0
- package/dist/web/signed-in.js +45 -0
- package/dist/web/signed-in.js.map +1 -0
- package/dist/web/site-index.d.ts +13 -0
- package/dist/web/site-index.d.ts.map +1 -0
- package/dist/web/site-index.js +142 -0
- package/dist/web/site-index.js.map +1 -0
- package/dist/web/site-view.d.ts +43 -0
- package/dist/web/site-view.d.ts.map +1 -0
- package/dist/web/site-view.js +65 -0
- package/dist/web/site-view.js.map +1 -0
- package/dist/web/sitemap.d.ts.map +1 -1
- package/dist/web/sitemap.js +5 -7
- package/dist/web/sitemap.js.map +1 -1
- package/dist/{admin → web}/throttle.d.ts +3 -4
- package/dist/web/throttle.d.ts.map +1 -0
- package/dist/{admin → web}/throttle.js +1 -2
- package/dist/web/throttle.js.map +1 -0
- package/dist/web/webmention-routes.d.ts +11 -0
- package/dist/web/webmention-routes.d.ts.map +1 -0
- package/dist/web/webmention-routes.js +51 -0
- package/dist/web/webmention-routes.js.map +1 -0
- package/dist/web/well-known.d.ts +2 -2
- package/dist/web/well-known.d.ts.map +1 -1
- package/dist/web/well-known.js +10 -20
- package/dist/web/well-known.js.map +1 -1
- package/dist/webmention/cited-picture.d.ts +1 -2
- package/dist/webmention/cited-picture.d.ts.map +1 -1
- package/dist/webmention/cited-picture.js +5 -7
- package/dist/webmention/cited-picture.js.map +1 -1
- package/dist/webmention/discovery.d.ts +2 -13
- package/dist/webmention/discovery.d.ts.map +1 -1
- package/dist/webmention/discovery.js +18 -73
- package/dist/webmention/discovery.js.map +1 -1
- package/dist/webmention/endpoint.d.ts +27 -0
- package/dist/webmention/endpoint.d.ts.map +1 -0
- package/dist/webmention/endpoint.js +26 -0
- package/dist/webmention/endpoint.js.map +1 -0
- package/dist/webmention/fetch-public.d.ts +18 -1
- package/dist/webmention/fetch-public.d.ts.map +1 -1
- package/dist/webmention/fetch-public.js +57 -23
- package/dist/webmention/fetch-public.js.map +1 -1
- package/dist/webmention/index.d.ts +11 -9
- package/dist/webmention/index.d.ts.map +1 -1
- package/dist/webmention/index.js +7 -6
- package/dist/webmention/index.js.map +1 -1
- package/dist/webmention/links.d.ts +0 -55
- package/dist/webmention/links.d.ts.map +1 -1
- package/dist/webmention/links.js +2 -185
- package/dist/webmention/links.js.map +1 -1
- package/dist/webmention/microformats.d.ts +1 -1
- package/dist/webmention/microformats.d.ts.map +1 -1
- package/dist/webmention/microformats.js +1 -1
- package/dist/webmention/microformats.js.map +1 -1
- package/dist/webmention/pingback.d.ts +13 -12
- package/dist/webmention/pingback.d.ts.map +1 -1
- package/dist/webmention/pingback.js +6 -113
- package/dist/webmention/pingback.js.map +1 -1
- package/dist/webmention/receive.d.ts +9 -4
- package/dist/webmention/receive.d.ts.map +1 -1
- package/dist/webmention/receive.js +35 -41
- package/dist/webmention/receive.js.map +1 -1
- package/dist/webmention/reply-context/fediverse.d.ts +29 -0
- package/dist/webmention/reply-context/fediverse.d.ts.map +1 -0
- package/dist/webmention/reply-context/fediverse.js +59 -0
- package/dist/webmention/reply-context/fediverse.js.map +1 -0
- package/dist/webmention/reply-context/json-ld.d.ts +5 -0
- package/dist/webmention/reply-context/json-ld.d.ts.map +1 -0
- package/dist/webmention/reply-context/json-ld.js +78 -0
- package/dist/webmention/reply-context/json-ld.js.map +1 -0
- package/dist/webmention/reply-context/oembed.d.ts +21 -0
- package/dist/webmention/reply-context/oembed.d.ts.map +1 -0
- package/dist/webmention/reply-context/oembed.js +137 -0
- package/dist/webmention/reply-context/oembed.js.map +1 -0
- package/dist/webmention/reply-context/page.d.ts +30 -0
- package/dist/webmention/reply-context/page.d.ts.map +1 -0
- package/dist/webmention/reply-context/page.js +134 -0
- package/dist/webmention/reply-context/page.js.map +1 -0
- package/dist/webmention/reply-context/source.d.ts +29 -0
- package/dist/webmention/reply-context/source.d.ts.map +1 -0
- package/dist/webmention/reply-context/source.js +46 -0
- package/dist/webmention/reply-context/source.js.map +1 -0
- package/dist/webmention/reply-context.d.ts +5 -34
- package/dist/webmention/reply-context.d.ts.map +1 -1
- package/dist/webmention/reply-context.js +9 -432
- package/dist/webmention/reply-context.js.map +1 -1
- package/dist/webmention/reply-contexts.d.ts +17 -6
- package/dist/webmention/reply-contexts.d.ts.map +1 -1
- package/dist/webmention/reply-contexts.js +19 -20
- package/dist/webmention/reply-contexts.js.map +1 -1
- package/dist/webmention/routes.d.ts +1 -1
- package/dist/webmention/routes.d.ts.map +1 -1
- package/dist/webmention/routes.js +5 -8
- package/dist/webmention/routes.js.map +1 -1
- package/dist/webmention/service.d.ts +9 -7
- package/dist/webmention/service.d.ts.map +1 -1
- package/dist/webmention/service.js +111 -110
- package/dist/webmention/service.js.map +1 -1
- package/dist/webmention/syndication.d.ts +3 -26
- package/dist/webmention/syndication.d.ts.map +1 -1
- package/dist/webmention/syndication.js +6 -20
- package/dist/webmention/syndication.js.map +1 -1
- package/package.json +17 -11
- package/themes/default/README.md +36 -2339
- package/themes/default/layouts/base.njk +5 -4
- package/themes/default/layouts/front-page.njk +4 -3
- package/themes/default/layouts/page.njk +2 -0
- package/themes/default/partials/comment-form.njk +1 -1
- package/themes/default/partials/contact-form.njk +1 -2
- package/themes/default/partials/conversation.njk +1 -2
- package/themes/default/partials/markdown-footer.md.njk +24 -0
- package/themes/default/partials/markdown-header.md.njk +31 -0
- package/themes/default/partials/post-list.njk +11 -11
- package/themes/default/src/style.css +18 -6
- package/themes/default/static/style.css +19 -0
- package/dist/admin/accounts.d.ts.map +0 -1
- package/dist/admin/accounts.js.map +0 -1
- package/dist/admin/admin-theme.d.ts.map +0 -1
- package/dist/admin/admin-theme.js.map +0 -1
- package/dist/admin/enclosure-field.d.ts.map +0 -1
- package/dist/admin/enclosure-field.js.map +0 -1
- package/dist/admin/event-field.d.ts.map +0 -1
- package/dist/admin/event-field.js.map +0 -1
- package/dist/admin/location-field.d.ts +0 -27
- package/dist/admin/location-field.d.ts.map +0 -1
- package/dist/admin/location-field.js.map +0 -1
- package/dist/admin/passwords.d.ts.map +0 -1
- package/dist/admin/passwords.js.map +0 -1
- package/dist/admin/photo-field.d.ts +0 -38
- package/dist/admin/photo-field.d.ts.map +0 -1
- package/dist/admin/photo-field.js.map +0 -1
- package/dist/admin/read-field.d.ts +0 -22
- package/dist/admin/read-field.d.ts.map +0 -1
- package/dist/admin/read-field.js +0 -61
- package/dist/admin/read-field.js.map +0 -1
- package/dist/admin/session.d.ts.map +0 -1
- package/dist/admin/session.js.map +0 -1
- package/dist/admin/store.d.ts +0 -1025
- package/dist/admin/store.d.ts.map +0 -1
- package/dist/admin/store.js +0 -1628
- package/dist/admin/store.js.map +0 -1
- package/dist/admin/throttle.d.ts.map +0 -1
- package/dist/admin/throttle.js.map +0 -1
- package/dist/avatars/routes.d.ts.map +0 -1
- package/dist/avatars/routes.js.map +0 -1
- package/dist/contact/routes.d.ts.map +0 -1
- package/dist/contact/routes.js.map +0 -1
- package/dist/env.d.ts.map +0 -1
- package/dist/env.js.map +0 -1
- package/dist/federation/replies.d.ts.map +0 -1
- package/dist/federation/replies.js.map +0 -1
- package/dist/images/alt-text.d.ts.map +0 -1
- package/dist/images/alt-text.js.map +0 -1
- package/dist/indieauth/activity-log.d.ts.map +0 -1
- package/dist/indieauth/activity-log.js.map +0 -1
- package/dist/indieauth/app-activity.d.ts.map +0 -1
- package/dist/indieauth/app-activity.js.map +0 -1
- package/dist/indieauth/bearer.d.ts.map +0 -1
- package/dist/indieauth/bearer.js.map +0 -1
- package/dist/indieauth/client-id.d.ts.map +0 -1
- package/dist/indieauth/client-id.js.map +0 -1
- package/dist/indieauth/connected-apps.d.ts.map +0 -1
- package/dist/indieauth/connected-apps.js.map +0 -1
- package/dist/indieauth/consent.d.ts.map +0 -1
- package/dist/indieauth/consent.js.map +0 -1
- package/dist/indieauth/discovery.d.ts.map +0 -1
- package/dist/indieauth/discovery.js.map +0 -1
- package/dist/indieauth/token.d.ts.map +0 -1
- package/dist/indieauth/token.js.map +0 -1
- package/dist/mail/service.d.ts.map +0 -1
- package/dist/mail/service.js.map +0 -1
- package/dist/mail/templates.d.ts.map +0 -1
- package/dist/mail/templates.js.map +0 -1
- package/dist/notifications/preferences.d.ts.map +0 -1
- package/dist/notifications/preferences.js.map +0 -1
- package/dist/notifications/routes.d.ts.map +0 -1
- package/dist/notifications/routes.js.map +0 -1
- package/dist/plugins/federation.d.ts.map +0 -1
- package/dist/plugins/federation.js.map +0 -1
- package/dist/plugins/mount.d.ts.map +0 -1
- package/dist/plugins/mount.js.map +0 -1
- package/dist/privacy/policy.d.ts.map +0 -1
- package/dist/privacy/policy.js.map +0 -1
- package/dist/web/admin-bar.d.ts.map +0 -1
- package/dist/web/admin-bar.js.map +0 -1
- package/dist/web/assets.d.ts.map +0 -1
- package/dist/web/assets.js.map +0 -1
- package/dist/web/authors.d.ts.map +0 -1
- package/dist/web/authors.js +0 -211
- package/dist/web/authors.js.map +0 -1
- package/dist/web/documents.d.ts +0 -81
- package/dist/web/documents.d.ts.map +0 -1
- package/dist/web/documents.js.map +0 -1
- package/dist/web/errors.d.ts.map +0 -1
- package/dist/web/errors.js.map +0 -1
- package/dist/web/guids.d.ts.map +0 -1
- package/dist/web/guids.js.map +0 -1
- package/dist/web/indexnow.d.ts.map +0 -1
- package/dist/web/indexnow.js.map +0 -1
- package/dist/web/license.d.ts.map +0 -1
- package/dist/web/license.js.map +0 -1
- package/dist/web/locale.d.ts.map +0 -1
- package/dist/web/locale.js.map +0 -1
- package/dist/web/navigation.d.ts.map +0 -1
- package/dist/web/navigation.js.map +0 -1
- package/dist/web/recent.d.ts +0 -43
- package/dist/web/recent.d.ts.map +0 -1
- package/dist/web/recent.js +0 -37
- package/dist/web/recent.js.map +0 -1
- package/dist/web/sanitize.d.ts +0 -29
- package/dist/web/sanitize.d.ts.map +0 -1
- package/dist/web/sanitize.js.map +0 -1
- package/dist/web/taxonomy.d.ts.map +0 -1
- package/dist/web/taxonomy.js.map +0 -1
- package/dist/web/templates.d.ts.map +0 -1
- package/dist/web/templates.js.map +0 -1
- package/dist/web/themes.d.ts.map +0 -1
- package/dist/web/themes.js.map +0 -1
- package/dist/webmention/html.d.ts.map +0 -1
- package/dist/webmention/html.js.map +0 -1
- package/dist/webmention/public-address.d.ts.map +0 -1
- package/dist/webmention/public-address.js.map +0 -1
- /package/dist/{web → content}/license.d.ts +0 -0
- /package/dist/{web → content}/license.js +0 -0
- /package/dist/{admin → site}/admin-theme.d.ts +0 -0
- /package/dist/{admin → site}/admin-theme.js +0 -0
- /package/dist/{admin → site}/passwords.d.ts +0 -0
- /package/dist/{admin → site}/passwords.js +0 -0
- /package/dist/{indieauth → util}/client-id.d.ts +0 -0
- /package/dist/{indieauth → util}/client-id.js +0 -0
- /package/dist/{webmention → util}/public-address.d.ts +0 -0
- /package/dist/{webmention → util}/public-address.js +0 -0
- /package/dist/{env.js → web/env.js} +0 -0
package/dist/web/routes.js
CHANGED
|
@@ -1,42 +1,38 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import { COMMENT_PAGE_PREFIX } from './guids.js';
|
|
25
|
-
import { goneDocumentAt, isGone, isListed, isServed, permalinkOfObjectId, previewDocumentAt, publicDocumentAt, } from './documents.js';
|
|
26
|
-
import { commentsFeedPath, REPLIES_ROOT, repliesFeedPath, commentsFeedResponse, feedPathUnder, feedResponse, feedSize, splitFeedPath, COMMENTS_ROOT, COMMENTS_TITLE_PREFIX, FEED_FORMATS, FEED_SEGMENTS, } from './feeds.js';
|
|
27
|
-
import { absoluteUrl, DOCUMENT_REPRESENTATIONS, documentJson, LISTING_REPRESENTATIONS, SEARCH_REPRESENTATIONS, lastModifiedOf, latestModified, MEDIA_TYPES, notAcceptableResponse, representationHref, representationEtag, representationResponse, selectRepresentation, splitRepresentationExtension, } from './negotiate.js';
|
|
28
|
-
import { offsetForPage, paginate } from './pagination.js';
|
|
29
|
-
import { TEMPLATES } from './render.js';
|
|
30
|
-
import { robotsResponse, ROBOTS_PATH } from './robots.js';
|
|
31
|
-
import { sitemapResponse, SITEMAP_CHILD_ROUTE, SITEMAP_PATH } from './sitemap.js';
|
|
1
|
+
import { mountAvatars } from './avatar-routes.js';
|
|
2
|
+
import { mountComments } from './comment-routes.js';
|
|
3
|
+
import { mountContact } from './contact-routes.js';
|
|
4
|
+
import { COMMENT_PAGE_PREFIX } from '../content/guids.js';
|
|
5
|
+
import { findPathRedirect, findQueryRedirect, redirectLocation } from '../content/redirects.js';
|
|
6
|
+
import { UPLOAD_ASSET_PREFIX, VARIANT_ASSET_PREFIX } from '../content/uploads.js';
|
|
7
|
+
import { iconSetting } from '../images/icons.js';
|
|
8
|
+
import { advertiseIdentityEndpoints } from './indieauth-discovery.js';
|
|
9
|
+
import { mountNotificationLinks } from './notification-routes.js';
|
|
10
|
+
import { robotsPolicyOf } from '../site/settings.js';
|
|
11
|
+
import { mountPingbacks } from './pingback-routes.js';
|
|
12
|
+
import { mountWebmentions } from './webmention-routes.js';
|
|
13
|
+
import { favicon, imageVariant, themeAsset, upload } from './asset-routes.js';
|
|
14
|
+
import { THEME_ASSET_PREFIX } from '../theme/assets.js';
|
|
15
|
+
import { negotiateDocument } from './document-page.js';
|
|
16
|
+
import { goneDocumentAt, previewDocumentAt } from '../content/permalinks.js';
|
|
17
|
+
import { embedView, oEmbed } from './embed.js';
|
|
18
|
+
import { commentPage, comments, feed, repliesFeed } from './feed-routes.js';
|
|
19
|
+
import { feedPathUnder, FEED_FORMATS, REPLIES_ROOT, splitFeedPath } from './feeds.js';
|
|
20
|
+
import { indexNowKeyPath, indexNowKeyResponse } from '../site/indexnow-key.js';
|
|
21
|
+
import { listing, search } from './listing-pages.js';
|
|
22
|
+
import { feedHref, SITE_POSTS } from './listing-subject.js';
|
|
23
|
+
import { LLMS_TXT_LINK, LLMS_TXT_PATH } from './llms.js';
|
|
32
24
|
import { FAVICON_PATH, manifestResponse, MANIFEST_PATH, webManifest } from './manifest.js';
|
|
25
|
+
import { DOCUMENT_REPRESENTATIONS, LISTING_REPRESENTATIONS, representationHref, SEARCH_REPRESENTATIONS, splitRepresentationExtension, } from './negotiate.js';
|
|
26
|
+
import { EMBED_PATH, OEMBED_PATH } from './oembed.js';
|
|
33
27
|
import { openSearchDescription, openSearchResponse, OPENSEARCH_PATH } from './opensearch.js';
|
|
34
|
-
import {
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
39
|
-
import {
|
|
28
|
+
import { canonicalHref, classifyPath, commentsFeedHref, movedHref, parseTermPath, slashedHref, } from './paths.js';
|
|
29
|
+
import { conditionalHeaders, encodePath, gone, notFound, queryFeedFormat, requestPath, requestSearch, selectFromAccept, } from './request.js';
|
|
30
|
+
import { robotsResponse, ROBOTS_PATH } from './robots.js';
|
|
31
|
+
import { SEARCH_PATH } from './search.js';
|
|
32
|
+
import { llmsTxt, sitemap } from './site-index.js';
|
|
33
|
+
import { siteView } from './site-view.js';
|
|
34
|
+
import { SITEMAP_CHILD_ROUTE, SITEMAP_PATH } from './sitemap.js';
|
|
35
|
+
import { redirectedTerm, termHref } from '../content/taxonomy.js';
|
|
40
36
|
/**
|
|
41
37
|
* Register the public site on a Hono app.
|
|
42
38
|
*
|
|
@@ -45,10 +41,9 @@ import { PAGE_SEGMENT, redirectedTerm, taxonomyForSegment, termHref } from './ta
|
|
|
45
41
|
* routes registered after this one still win, and a permalink can never shadow
|
|
46
42
|
* them, because the document lookup only runs once nothing else has matched.
|
|
47
43
|
*/
|
|
48
|
-
export function mountPublicSite(app) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
app.use('*', publicAdminBar);
|
|
44
|
+
export function mountPublicSite(app, { adminBar } = {}) {
|
|
45
|
+
if (adminBar !== undefined)
|
|
46
|
+
app.use('*', adminBar);
|
|
52
47
|
app.use('*', advertiseIdentityEndpoints);
|
|
53
48
|
app.use('*', declaredQueryRedirect);
|
|
54
49
|
app.get(`${THEME_ASSET_PREFIX}*`, themeAsset);
|
|
@@ -79,40 +74,24 @@ export function mountPublicSite(app) {
|
|
|
79
74
|
// whole of WordPress's "Your homepage displays", decided per request off
|
|
80
75
|
// `site.json` so a save on the settings screen moves the front page on the
|
|
81
76
|
// very next one.
|
|
82
|
-
const home =
|
|
77
|
+
const home = siteView(c).pages.home;
|
|
83
78
|
const response = home === undefined
|
|
84
|
-
? listing(c, {
|
|
85
|
-
: negotiateDocument(c, home, selectFromAccept(c, DOCUMENT_REPRESENTATIONS)
|
|
79
|
+
? listing(c, { subject: SITE_POSTS, pageNumber: 0 })
|
|
80
|
+
: negotiateDocument(c, home, selectFromAccept(c, DOCUMENT_REPRESENTATIONS));
|
|
86
81
|
// The home page is where a tool that found the site looks for its index
|
|
87
82
|
// (TASK-149): a header, so it is found without parsing the page.
|
|
88
|
-
if (
|
|
83
|
+
if (c.var.siteAtRequestStart.llms_txt) {
|
|
89
84
|
response.headers.append('link', LLMS_TXT_LINK);
|
|
90
85
|
}
|
|
91
86
|
return response;
|
|
92
87
|
});
|
|
93
|
-
app.get(`/${PAGE_SEGMENT}/:page{[0-9]+}/`, (c) => {
|
|
94
|
-
const requested = Number(c.req.param('page'));
|
|
95
|
-
// Page one is the home page; it does not get a second URL.
|
|
96
|
-
if (requested <= 1)
|
|
97
|
-
return c.redirect('/', 301);
|
|
98
|
-
const pages = frontPages(c);
|
|
99
|
-
// With a posts page, the listing's pages live under it and these are the
|
|
100
|
-
// URLs they used to have; with a static homepage and no posts page, the
|
|
101
|
-
// listing has no page of its own and neither have its pages.
|
|
102
|
-
if (pages.posts !== undefined) {
|
|
103
|
-
return c.redirect(listingPageHref(pages.posts.permalink, requested - 1), 301);
|
|
104
|
-
}
|
|
105
|
-
if (pages.home !== undefined)
|
|
106
|
-
return notFound(c);
|
|
107
|
-
return listing(c, { term: undefined, pageNumber: requested - 1 });
|
|
108
|
-
});
|
|
109
88
|
// The site's own feeds are routes rather than representations, so a reader's
|
|
110
89
|
// careless `Accept` header cannot land it on the HTML (doc-3), and so a
|
|
111
90
|
// document permalinked at `/feed/` cannot take the subscribers' URL. Their
|
|
112
91
|
// paths are fixed — only the taxonomy feeds hang off a configurable base —
|
|
113
92
|
// so the route table can hold them.
|
|
114
93
|
for (const format of FEED_FORMATS) {
|
|
115
|
-
app.get(feedPathUnder('/', format), (c) => feed(c, format,
|
|
94
|
+
app.get(feedPathUnder('/', format), (c) => feed(c, format, SITE_POSTS));
|
|
116
95
|
}
|
|
117
96
|
// The site-wide comments feed, for the same reason and at WordPress's URL.
|
|
118
97
|
app.get(commentsFeedHref(undefined), (c) => comments(c, undefined));
|
|
@@ -127,7 +106,7 @@ export function mountPublicSite(app) {
|
|
|
127
106
|
// search engine polls.
|
|
128
107
|
app.get(SITEMAP_PATH, (c) => sitemap(c, undefined));
|
|
129
108
|
app.get(SITEMAP_CHILD_ROUTE, (c) => sitemap(c, Number(c.req.param('page'))));
|
|
130
|
-
app.get(ROBOTS_PATH, (c) => robotsResponse(c.var.config.baseUrl, conditionalHeaders(c), robotsPolicyOf(
|
|
109
|
+
app.get(ROBOTS_PATH, (c) => robotsResponse(c.var.config.baseUrl, conditionalHeaders(c), robotsPolicyOf(c.var.siteAtRequestStart)));
|
|
131
110
|
// The web app manifest and the root favicon (TASK-147), fixed paths at the
|
|
132
111
|
// root for the same reason: a browser asks for `/favicon.ico` whatever the
|
|
133
112
|
// head links, and no permalink may take either URL.
|
|
@@ -153,22 +132,15 @@ export function mountPublicSite(app) {
|
|
|
153
132
|
// same prefix: the one response another site may put in a frame.
|
|
154
133
|
app.get(EMBED_PATH, embedView);
|
|
155
134
|
// The index for language models (TASK-149), a fixed path at the root for
|
|
156
|
-
// the same reason.
|
|
157
|
-
|
|
158
|
-
app.get(LLMS_TXT_PATH, (c) => {
|
|
159
|
-
const { contentDir, baseUrl } = c.var.config;
|
|
160
|
-
if (!readSiteSettings(contentDir).llmsTxt)
|
|
161
|
-
return notFound(c);
|
|
162
|
-
const file = ownLlmsTxt(contentDir) ?? generatedLlmsTxt(llmsIndex(c), baseUrl);
|
|
163
|
-
return llmsTxtResponse(file, conditionalHeaders(c));
|
|
164
|
-
});
|
|
135
|
+
// the same reason.
|
|
136
|
+
app.get(LLMS_TXT_PATH, llmsTxt);
|
|
165
137
|
// The IndexNow key file (TASK-151), at the root because that is where an
|
|
166
138
|
// engine checks for it. Any other `.txt` path is not this route's: it falls
|
|
167
139
|
// through to whatever document or 404 would have answered it.
|
|
168
140
|
app.get('/:file{[A-Za-z0-9-]{8,128}\\.txt}', async (c, next) => {
|
|
169
|
-
const settings =
|
|
170
|
-
const key = settings.
|
|
171
|
-
if (!settings.
|
|
141
|
+
const settings = c.var.siteAtRequestStart;
|
|
142
|
+
const key = settings.index_now_key;
|
|
143
|
+
if (!settings.index_now || key === '' || c.req.path !== indexNowKeyPath(key)) {
|
|
172
144
|
await next();
|
|
173
145
|
return;
|
|
174
146
|
}
|
|
@@ -182,73 +154,13 @@ export function mountPublicSite(app) {
|
|
|
182
154
|
// the way to the real one.
|
|
183
155
|
app.get(SEARCH_PATH, (c) => search(c, selectFromAccept(c, SEARCH_REPRESENTATIONS)));
|
|
184
156
|
app.get(representationHref(SEARCH_PATH, 'json'), (c) => search(c, 'json'));
|
|
185
|
-
app.get(SEARCH_PATH.slice(0, -1), (c) => c.redirect(`${SEARCH_PATH}${
|
|
186
|
-
// The
|
|
187
|
-
// when the app is built and the bases
|
|
188
|
-
// resolved per request in the not-found
|
|
189
|
-
// holds at that moment (TASK-36).
|
|
157
|
+
app.get(SEARCH_PATH.slice(0, -1), (c) => c.redirect(`${SEARCH_PATH}${requestSearch(c)}`, 301));
|
|
158
|
+
// The archives and the home listing's pages are deliberately not routes. A
|
|
159
|
+
// route table is fixed when the app is built, and the bases and the posts
|
|
160
|
+
// page are settings, so a listing is resolved per request in the not-found
|
|
161
|
+
// handler, from what the site holds at that moment (TASK-36).
|
|
190
162
|
app.notFound(resolveRequest);
|
|
191
163
|
}
|
|
192
|
-
/**
|
|
193
|
-
* The oEmbed of the post or page a URL names, a 404 when it names none, and a
|
|
194
|
-
* 501 for a format the spec allows and this provider does not serve.
|
|
195
|
-
*/
|
|
196
|
-
function oEmbed(c) {
|
|
197
|
-
const request = oEmbedRequest((name) => c.req.query(name));
|
|
198
|
-
const found = embeddableAt(c, request.url);
|
|
199
|
-
if (found === undefined)
|
|
200
|
-
return notFound(c);
|
|
201
|
-
if (request.format === undefined)
|
|
202
|
-
return c.text('Not Implemented', 501);
|
|
203
|
-
const embed = oEmbedFor({ ...embedSubject(c, found), config: c.var.config, request });
|
|
204
|
-
return oEmbedResponse(embed, request.format, conditionalHeaders(c));
|
|
205
|
-
}
|
|
206
|
-
/**
|
|
207
|
-
* The card of the post or page a URL names as a page another site may frame,
|
|
208
|
-
* and a 404, framed by nobody else, when it names none.
|
|
209
|
-
*/
|
|
210
|
-
function embedView(c) {
|
|
211
|
-
const found = embeddableAt(c, c.req.query('url') ?? '');
|
|
212
|
-
if (found === undefined)
|
|
213
|
-
return notFound(c);
|
|
214
|
-
c.set('frameable', true);
|
|
215
|
-
return embedResponse(embedPage(embedSubject(c, found)), conditionalHeaders(c));
|
|
216
|
-
}
|
|
217
|
-
/** What an embed of `found` is drawn from, with the byline it names. */
|
|
218
|
-
function embedSubject(c, found) {
|
|
219
|
-
const site = c.var.renderer.site();
|
|
220
|
-
const users = listUsers(c.var.config.dataDir);
|
|
221
|
-
return {
|
|
222
|
-
...found,
|
|
223
|
-
label: postLabel(found.document, (url) => c.var.replyContexts.read(url)),
|
|
224
|
-
// Who the byline names: the document's author, else the site's.
|
|
225
|
-
author: authorContext(users, found.document.author) ?? siteAuthorContext(users, site.author),
|
|
226
|
-
config: c.var.config,
|
|
227
|
-
site,
|
|
228
|
-
};
|
|
229
|
-
}
|
|
230
|
-
/**
|
|
231
|
-
* The published post or page an absolute URL is the page of, and where it is
|
|
232
|
-
* served, or `undefined`.
|
|
233
|
-
*
|
|
234
|
-
* The same lookup a request for that URL makes, so an embed exists exactly
|
|
235
|
-
* where a page does: a URL on this site's origin and under its base path,
|
|
236
|
-
* with no query, at a public document's permalink. `/` is the static
|
|
237
|
-
* homepage when there is one, and the posts page is the listing it carries
|
|
238
|
-
* rather than a page to embed.
|
|
239
|
-
*/
|
|
240
|
-
function embeddableAt(c, url) {
|
|
241
|
-
const pathname = permalinkOfObjectId(url, c.var.config.baseUrl);
|
|
242
|
-
if (pathname === undefined)
|
|
243
|
-
return undefined;
|
|
244
|
-
const pages = frontPages(c);
|
|
245
|
-
if (pathname === '/')
|
|
246
|
-
return pages.home === undefined ? undefined : { document: pages.home, href: '/' };
|
|
247
|
-
const document = publicDocumentAt(c.var.store, pathname);
|
|
248
|
-
if (document === undefined || document.path === pages.posts?.path)
|
|
249
|
-
return undefined;
|
|
250
|
-
return { document, href: document.path === pages.home?.path ? '/' : document.permalink };
|
|
251
|
-
}
|
|
252
164
|
/**
|
|
253
165
|
* A declared redirect whose source names a query, WordPress's `/?p=123` above
|
|
254
166
|
* all (TASK-128). It is answered before any route because `/` is one the
|
|
@@ -257,7 +169,7 @@ function embeddableAt(c, url) {
|
|
|
257
169
|
*/
|
|
258
170
|
const declaredQueryRedirect = async (c, next) => {
|
|
259
171
|
if (c.req.method === 'GET' || c.req.method === 'HEAD') {
|
|
260
|
-
const
|
|
172
|
+
const search = requestSearch(c);
|
|
261
173
|
const redirect = search === ''
|
|
262
174
|
? undefined
|
|
263
175
|
: findQueryRedirect(c.var.redirects.current(), requestPath(c), search);
|
|
@@ -266,132 +178,56 @@ const declaredQueryRedirect = async (c, next) => {
|
|
|
266
178
|
}
|
|
267
179
|
await next();
|
|
268
180
|
};
|
|
269
|
-
/**
|
|
270
|
-
* The last stop for a request: a taxonomy archive or one of its feeds, the
|
|
271
|
-
* document at this URL, the same document in the representation a `.md` or
|
|
272
|
-
* `.json` suffix asked for, the canonical URL it should have asked for, or the
|
|
273
|
-
* theme's 404.
|
|
274
|
-
*
|
|
275
|
-
* The archives come first, so an archive URL means the archive however a
|
|
276
|
-
* document is permalinked; they are here rather than in the route table
|
|
277
|
-
* because their bases are a setting, and a route table is fixed when the app
|
|
278
|
-
* is built. The suffix is stripped and the *same* {@link publicDocumentAt}
|
|
279
|
-
* lookup runs again, so no representation can resolve to a document the others
|
|
280
|
-
* cannot see.
|
|
281
|
-
*/
|
|
282
181
|
function resolveRequest(c) {
|
|
283
|
-
const
|
|
182
|
+
const view = siteView(c);
|
|
284
183
|
const pathname = requestPath(c);
|
|
285
|
-
const
|
|
286
|
-
const
|
|
287
|
-
const
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
const request = postsPageRequest(pages.posts, pathname);
|
|
293
|
-
if (request !== undefined) {
|
|
294
|
-
// `{permalink}page/1/` is the listing's own URL spelled twice, and
|
|
295
|
-
// collapses onto it exactly as `/page/1/` collapses onto `/`.
|
|
296
|
-
if (request.pageNumber === 0 && pathname !== pages.posts.permalink) {
|
|
297
|
-
return c.redirect(encodePath(pages.posts.permalink), 301);
|
|
298
|
-
}
|
|
299
|
-
return listing(c, request);
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
const feedRequest = parseFeedPath(c, pathname, bases, authors);
|
|
303
|
-
if (feedRequest !== undefined) {
|
|
304
|
-
const { target, format } = feedRequest;
|
|
305
|
-
const canonical = feedTargetHref(target, format, bases);
|
|
306
|
-
if (!feedRequest.canonical ||
|
|
307
|
-
(target.kind === 'listing' && canonical !== encodePath(pathname))) {
|
|
308
|
-
return c.redirect(canonical, 301);
|
|
309
|
-
}
|
|
310
|
-
return target.kind === 'listing'
|
|
311
|
-
? feed(c, format, target.subject)
|
|
312
|
-
: comments(c, target.document);
|
|
313
|
-
}
|
|
314
|
-
const archive = taxonomyArchive(c, pathname, bases, authors);
|
|
315
|
-
if (archive !== undefined)
|
|
316
|
-
return archive;
|
|
317
|
-
// And one person's, which is the same kind of thing at a path the site
|
|
318
|
-
// reserves: `author` is never a document's first segment, so this can be
|
|
319
|
-
// answered before the permalink lookup without anything being shadowed.
|
|
320
|
-
const byAuthor = authorArchive(c, pathname, bases, authors);
|
|
321
|
-
if (byAuthor !== undefined)
|
|
322
|
-
return byAuthor;
|
|
323
|
-
const document = publicDocumentAt(store, pathname);
|
|
324
|
-
if (document !== undefined) {
|
|
325
|
-
// The front page has one URL. The page it is made of keeps its own
|
|
326
|
-
// permalink in the file, so that a homepage put back to being an ordinary
|
|
327
|
-
// page goes back to answering there, and that URL points at `/` while it
|
|
328
|
-
// is the front page.
|
|
329
|
-
if (document.path === pages.home?.path)
|
|
330
|
-
return c.redirect('/', 301);
|
|
331
|
-
// WordPress answered `?feed=rss2` on a permalink with that document's
|
|
332
|
-
// comments feed, which is the only feed a document has here too. The other
|
|
333
|
-
// spellings name a format a comments feed does not come in, so they are
|
|
334
|
-
// not a feed request at all and the page is served.
|
|
335
|
-
if (queryFeedFormat(c) === 'rss' && showsConversation(c, document)) {
|
|
336
|
-
return c.redirect(commentsFeedHref(document), 301);
|
|
184
|
+
const search = requestSearch(c);
|
|
185
|
+
const here = encodePath(pathname);
|
|
186
|
+
const match = classifyPath(view, pathname);
|
|
187
|
+
if (match !== undefined) {
|
|
188
|
+
const href = canonicalHref(view, match);
|
|
189
|
+
if (href !== here || (match.kind === 'feed' && !match.canonical)) {
|
|
190
|
+
return c.redirect(`${href}${search}`, 301);
|
|
337
191
|
}
|
|
338
|
-
return
|
|
192
|
+
return serve(c, match);
|
|
339
193
|
}
|
|
340
194
|
const hidden = hiddenDocumentForSignedInHtml(c, pathname);
|
|
341
195
|
if (hidden !== undefined)
|
|
342
196
|
return hidden;
|
|
343
|
-
const { search } = new URL(c.req.url);
|
|
344
197
|
const extension = splitRepresentationExtension(pathname);
|
|
345
198
|
if (extension !== undefined) {
|
|
346
|
-
const
|
|
347
|
-
const href = representationHref(encodePath(candidate), extension.representation);
|
|
348
|
-
return href === encodePath(pathname) ? undefined : `${href}${search}`;
|
|
349
|
-
};
|
|
199
|
+
const { representation } = extension;
|
|
350
200
|
for (const candidate of extension.paths) {
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
}
|
|
363
|
-
// `/index.json`, `/page/2/index.json`, `/tag/x/index.json`,
|
|
364
|
-
// `/category/x/index.json`: the same escape hatch over a listing, for the
|
|
365
|
-
// representations a listing has.
|
|
366
|
-
if (LISTING_REPRESENTATIONS.includes(extension.representation)) {
|
|
367
|
-
for (const candidate of extension.paths) {
|
|
368
|
-
const request = listingRequestAt(store, pages, candidate, bases, authors);
|
|
369
|
-
if (request === undefined)
|
|
370
|
-
continue;
|
|
371
|
-
const canonical = canonicalRedirect(candidate);
|
|
372
|
-
if (canonical !== undefined)
|
|
373
|
-
return c.redirect(canonical, 301);
|
|
374
|
-
return listing(c, request, extension.representation);
|
|
375
|
-
}
|
|
201
|
+
const found = classifyPath(view, candidate);
|
|
202
|
+
if (found === undefined || found.kind === 'feed')
|
|
203
|
+
continue;
|
|
204
|
+
if (found.kind === 'listing' && !LISTING_REPRESENTATIONS.includes(representation))
|
|
205
|
+
continue;
|
|
206
|
+
const href = representationHref(canonicalHref(view, found), representation);
|
|
207
|
+
if (href !== here)
|
|
208
|
+
return c.redirect(`${href}${search}`, 301);
|
|
209
|
+
return found.kind === 'listing'
|
|
210
|
+
? listing(c, found, representation)
|
|
211
|
+
: negotiateDocument(c, found.document, representation);
|
|
376
212
|
}
|
|
377
213
|
}
|
|
378
214
|
// Nothing lives here, so a URL something used to live at leads on to where
|
|
379
215
|
// it lives now. Asked only after every live lookup, which is what lets a new
|
|
380
216
|
// document take an old URL over, and a term that comes back into use beat
|
|
381
217
|
// the record of what it was renamed to.
|
|
382
|
-
const formerly = movedHref(
|
|
218
|
+
const formerly = movedHref(view, pathname, undefined) ??
|
|
383
219
|
extension?.paths
|
|
384
|
-
.map((candidate) => movedHref(
|
|
220
|
+
.map((candidate) => movedHref(view, candidate, extension.representation))
|
|
385
221
|
.find((href) => href !== undefined) ??
|
|
386
|
-
renamedTermHref(c,
|
|
222
|
+
renamedTermHref(c, view, pathname);
|
|
387
223
|
if (formerly !== undefined)
|
|
388
224
|
return c.redirect(`${formerly}${search}`, 301);
|
|
389
|
-
const deleted = [pathname, ...(extension?.paths ?? [])].some((candidate) => goneDocumentAt(store, candidate) !== undefined);
|
|
225
|
+
const deleted = [pathname, ...(extension?.paths ?? [])].some((candidate) => goneDocumentAt(view.store, candidate) !== undefined);
|
|
390
226
|
if (deleted)
|
|
391
227
|
return gone(c);
|
|
392
|
-
const
|
|
393
|
-
if (
|
|
394
|
-
return c.redirect(
|
|
228
|
+
const slashed = slashedHref(view, pathname, c.var.renderer.pageSize());
|
|
229
|
+
if (slashed !== undefined)
|
|
230
|
+
return c.redirect(`${slashed}${search}`, 301);
|
|
395
231
|
// And a URL the site itself says has moved (TASK-128), after every live
|
|
396
232
|
// lookup and after the slash that would lead to one, so a declared source
|
|
397
233
|
// never shadows a live document.
|
|
@@ -401,55 +237,25 @@ function resolveRequest(c) {
|
|
|
401
237
|
}
|
|
402
238
|
return notFound(c);
|
|
403
239
|
}
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
* collapses onto the home page, and any other casing of a term collapses onto
|
|
422
|
-
* the site's spelling of it (TASK-339). A term nothing carries is not an
|
|
423
|
-
* archive at all, so the request goes on to the renames and the declared
|
|
424
|
-
* redirects that may know where it went.
|
|
425
|
-
*/
|
|
426
|
-
function taxonomyArchive(c, pathname, bases, authors) {
|
|
427
|
-
if (!pathname.endsWith('/'))
|
|
428
|
-
return undefined;
|
|
429
|
-
const request = parseListingPath(c.var.store, pathname, bases, authors);
|
|
430
|
-
if (request?.term === undefined)
|
|
431
|
-
return undefined;
|
|
432
|
-
const canonical = termHref(request.term, request.pageNumber, bases);
|
|
433
|
-
if (canonical !== encodePath(pathname)) {
|
|
434
|
-
return c.redirect(`${canonical}${new URL(c.req.url).search}`, 301);
|
|
240
|
+
function serve(c, match) {
|
|
241
|
+
switch (match.kind) {
|
|
242
|
+
case 'listing':
|
|
243
|
+
return listing(c, match);
|
|
244
|
+
case 'feed':
|
|
245
|
+
return match.target.kind === 'listing'
|
|
246
|
+
? feed(c, match.format, match.target.subject)
|
|
247
|
+
: comments(c, match.target.document);
|
|
248
|
+
case 'document':
|
|
249
|
+
// WordPress answered `?feed=rss2` on a permalink with that document's
|
|
250
|
+
// comments feed, which is the only feed a document has here too. The
|
|
251
|
+
// other spellings name a format a comments feed does not come in, so
|
|
252
|
+
// they are not a feed request at all and the page is served.
|
|
253
|
+
if (queryFeedFormat(c) === 'rss') {
|
|
254
|
+
return c.redirect(commentsFeedHref(match.document), 301);
|
|
255
|
+
}
|
|
256
|
+
return negotiateDocument(c, match.document, selectFromAccept(c, DOCUMENT_REPRESENTATIONS));
|
|
435
257
|
}
|
|
436
|
-
return listing(c, request);
|
|
437
258
|
}
|
|
438
|
-
/**
|
|
439
|
-
* One person's archive, the redirect that puts it at its canonical URL, or
|
|
440
|
-
* `undefined` when the path is not one.
|
|
441
|
-
*
|
|
442
|
-
* Unlike a taxonomy archive it does not depend on there being anything on it.
|
|
443
|
-
* A tag exists only while something carries it; a person exists because they
|
|
444
|
-
* have an account, and after decision-14 this URL is the id their followers
|
|
445
|
-
* file them under — so an archive that 404'd until its owner published would
|
|
446
|
-
* be an account that came into being with a post. What decides the 404 is
|
|
447
|
-
* whether the username is somebody's, which {@link parseListingPath} has
|
|
448
|
-
* already asked.
|
|
449
|
-
*
|
|
450
|
-
* `/author/{username}/page/1/` collapses onto the archive root the way
|
|
451
|
-
* `/page/1/` collapses onto the home page.
|
|
452
|
-
*/
|
|
453
259
|
function hiddenDocumentForSignedInHtml(c, pathname) {
|
|
454
260
|
if (c.var.signedIn === undefined)
|
|
455
261
|
return undefined;
|
|
@@ -458,17 +264,6 @@ function hiddenDocumentForSignedInHtml(c, pathname) {
|
|
|
458
264
|
const hidden = previewDocumentAt(c.var.store, pathname);
|
|
459
265
|
return hidden === undefined ? undefined : negotiateDocument(c, hidden, 'html');
|
|
460
266
|
}
|
|
461
|
-
function authorArchive(c, pathname, bases, authors) {
|
|
462
|
-
if (!pathname.endsWith('/'))
|
|
463
|
-
return undefined;
|
|
464
|
-
const request = parseListingPath(c.var.store, pathname, bases, authors);
|
|
465
|
-
if (request?.author === undefined)
|
|
466
|
-
return undefined;
|
|
467
|
-
const canonical = authorHref(request.author.user.username, request.pageNumber);
|
|
468
|
-
if (canonical !== encodePath(pathname))
|
|
469
|
-
return c.redirect(canonical, 301);
|
|
470
|
-
return listing(c, request);
|
|
471
|
-
}
|
|
472
267
|
/**
|
|
473
268
|
* Where a renamed term's archive page or feed lives now, or `undefined` when
|
|
474
269
|
* the path is neither or the site records no rename of its term.
|
|
@@ -477,9 +272,9 @@ function authorArchive(c, pathname, bases, authors) {
|
|
|
477
272
|
* to the old feed follows it to the new one, exactly as a reader of the archive
|
|
478
273
|
* does.
|
|
479
274
|
*/
|
|
480
|
-
function renamedTermHref(c,
|
|
275
|
+
function renamedTermHref(c, view, pathname) {
|
|
481
276
|
const feedPath = splitFeedPath(pathname);
|
|
482
|
-
const asked = parseTermPath(feedPath?.root ?? pathname
|
|
277
|
+
const asked = parseTermPath(view, feedPath?.root ?? pathname);
|
|
483
278
|
if (asked === undefined || (feedPath !== undefined && asked.pageNumber !== 0))
|
|
484
279
|
return undefined;
|
|
485
280
|
const to = redirectedTerm(c.var.renderer.termRedirects(), asked.term);
|
|
@@ -487,1074 +282,7 @@ function renamedTermHref(c, pathname, bases) {
|
|
|
487
282
|
return undefined;
|
|
488
283
|
const moved = { taxonomy: asked.term.taxonomy, term: to };
|
|
489
284
|
return feedPath === undefined
|
|
490
|
-
? termHref(moved, asked.pageNumber, bases)
|
|
491
|
-
: feedHref(moved, feedPath.format, bases);
|
|
492
|
-
}
|
|
493
|
-
/**
|
|
494
|
-
* A path as the feed it names: `/feed/`, `/feed/atom/`, `/{base}/x/feed/json/`,
|
|
495
|
-
* the comments feeds at `/comments/feed/` and `{permalink}feed/`, and the
|
|
496
|
-
* `/feed/rss/` spelling WordPress also answered at any of those roots.
|
|
497
|
-
*
|
|
498
|
-
* The site's own canonical feeds are real routes and never reach here; what
|
|
499
|
-
* does reach here is every taxonomy feed — their bases are a setting, so they
|
|
500
|
-
* cannot be in the route table — every document's comments feed, and every alias.
|
|
501
|
-
*/
|
|
502
|
-
function parseFeedPath(c, pathname, bases, authors) {
|
|
503
|
-
const { store } = c.var;
|
|
504
|
-
const split = splitFeedPath(pathname);
|
|
505
|
-
if (split === undefined)
|
|
506
|
-
return undefined;
|
|
507
|
-
const { format, canonical } = split;
|
|
508
|
-
if (split.root === COMMENTS_ROOT) {
|
|
509
|
-
return format === 'rss'
|
|
510
|
-
? { target: { kind: 'comments', document: undefined }, format, canonical }
|
|
511
|
-
: undefined;
|
|
512
|
-
}
|
|
513
|
-
const root = parseListingPath(store, split.root, bases, authors);
|
|
514
|
-
// Only a listing root has a feed, and only its first page: a feed is not
|
|
515
|
-
// paginated, so `/{base}/x/page/2/feed/` names nothing.
|
|
516
|
-
if (root !== undefined) {
|
|
517
|
-
return root.pageNumber === 0
|
|
518
|
-
? { target: { kind: 'listing', subject: root }, format, canonical }
|
|
519
|
-
: undefined;
|
|
520
|
-
}
|
|
521
|
-
// Otherwise it may be a document's comments feed, which it has exactly when
|
|
522
|
-
// its page shows its conversation.
|
|
523
|
-
if (format !== 'rss')
|
|
524
|
-
return undefined;
|
|
525
|
-
const document = publicDocumentAt(store, split.root);
|
|
526
|
-
if (document === undefined || !showsConversation(c, document))
|
|
527
|
-
return undefined;
|
|
528
|
-
return { target: { kind: 'comments', document }, format, canonical };
|
|
529
|
-
}
|
|
530
|
-
/** Whether this document's page shows its conversation, and so has a comments feed. */
|
|
531
|
-
function showsConversation(c, document) {
|
|
532
|
-
return answerable(document, commentPolicyOf(c.var.renderer.site()), c.var.store.now());
|
|
533
|
-
}
|
|
534
|
-
/** Where the canonical URL of one feed is. */
|
|
535
|
-
function feedTargetHref(target, format, bases) {
|
|
536
|
-
return target.kind === 'listing'
|
|
537
|
-
? listingFeedHref(target.subject, format, bases)
|
|
538
|
-
: commentsFeedHref(target.document);
|
|
539
|
-
}
|
|
540
|
-
/**
|
|
541
|
-
* The format `?feed=` asked for, WordPress's pre-permalink spelling, or
|
|
542
|
-
* `undefined` when the request did not ask for a feed at all.
|
|
543
|
-
*
|
|
544
|
-
* `rss2` is what WordPress calls RSS 2.0 and `rss` its RSS 0.92, which this
|
|
545
|
-
* site does not serve and answers with the RSS 2.0 feed rather than a 404.
|
|
546
|
-
*/
|
|
547
|
-
function queryFeedFormat(c) {
|
|
548
|
-
const asked = c.req.query('feed');
|
|
549
|
-
if (asked === undefined)
|
|
550
|
-
return undefined;
|
|
551
|
-
if (asked === 'rss2' || asked === 'rss')
|
|
552
|
-
return 'rss';
|
|
553
|
-
return FEED_FORMATS.find((format) => FEED_SEGMENTS[format] === asked);
|
|
554
|
-
}
|
|
555
|
-
/**
|
|
556
|
-
* What the query string puts on a rendered post, if anything.
|
|
557
|
-
*
|
|
558
|
-
* A reader has no session, so the message after a submission travels in the
|
|
559
|
-
* URL and is read back here. An unknown value says nothing at all rather than
|
|
560
|
-
* being printed, so the query cannot be used to put words on somebody's post.
|
|
561
|
-
*/
|
|
562
|
-
function commentNotice(c, document, viewer) {
|
|
563
|
-
const notice = commentNoticeFor(c.req.query(COMMENT_NOTICE_PARAM));
|
|
564
|
-
return {
|
|
565
|
-
...(notice === undefined ? {} : { commentNotice: notice }),
|
|
566
|
-
// And who a Reply link says the form is answering, which travels the same
|
|
567
|
-
// way and for the same reason: a reader has no session, and threading
|
|
568
|
-
// should not need a line of JavaScript.
|
|
569
|
-
...commentReplyTarget({
|
|
570
|
-
admin: c.var.admin,
|
|
571
|
-
document,
|
|
572
|
-
id: c.req.query(COMMENT_REPLY_PARAM),
|
|
573
|
-
thread: viewer === undefined ? undefined : c.var.conversation.thread(document),
|
|
574
|
-
}),
|
|
575
|
-
// And the thank-you after a contact form was sent, which travels the same
|
|
576
|
-
// way for the same reason (TASK-56).
|
|
577
|
-
...contactNotice(c),
|
|
578
|
-
};
|
|
579
|
-
}
|
|
580
|
-
/**
|
|
581
|
-
* The thank-you a contact form's redirect landed on, if the query names one.
|
|
582
|
-
*
|
|
583
|
-
* On the context rather than in the form's own state because the redirect is
|
|
584
|
-
* what makes a refresh harmless: the page is drawn fresh, and the query is the
|
|
585
|
-
* only thing that says a message went.
|
|
586
|
-
*/
|
|
587
|
-
function contactNotice(c) {
|
|
588
|
-
const notice = contactNoticeFor(c.req.query(CONTACT_NOTICE_PARAM));
|
|
589
|
-
return notice === undefined ? {} : { contactNotice: notice };
|
|
590
|
-
}
|
|
591
|
-
/** The representation an `Accept` header asked for, or `undefined` for a 406. */
|
|
592
|
-
function selectFromAccept(c, available) {
|
|
593
|
-
return selectRepresentation(c.req.header('accept'), available);
|
|
594
|
-
}
|
|
595
|
-
/**
|
|
596
|
-
* One document in one representation, or the 406 an impossible `Accept` earns.
|
|
597
|
-
*
|
|
598
|
-
* `href` is where it is being served, which is its own permalink everywhere
|
|
599
|
-
* but the front page: a page serving as the homepage is read at `/`, and the
|
|
600
|
-
* canonical URL, the alternates and the theme's own links have to say so.
|
|
601
|
-
*/
|
|
602
|
-
function negotiateDocument(c, document, representation, href = document.permalink) {
|
|
603
|
-
if (representation === undefined) {
|
|
604
|
-
return notAcceptableResponse(encodePath(href), DOCUMENT_REPRESENTATIONS);
|
|
605
|
-
}
|
|
606
|
-
// Who the request's session says is reading, when it says anybody
|
|
607
|
-
// (TASK-103). Only the HTML has a form on it, so only the HTML asks; the
|
|
608
|
-
// Markdown and JSON of a post are the same bytes for everybody.
|
|
609
|
-
const account = representation === 'html' ? c.var.signedIn : undefined;
|
|
610
|
-
const viewer = account === undefined ? undefined : commenterOf(account);
|
|
611
|
-
// And which document it is, so the admin bar can offer its editor.
|
|
612
|
-
if (representation === 'html')
|
|
613
|
-
c.set('shownDocument', document);
|
|
614
|
-
const listed = isListed(document, c.var.store.now());
|
|
615
|
-
// The thank-you after a comment was posted, which the redirect carried back
|
|
616
|
-
// as a query, is the only thing about a document's HTML that the URL rather
|
|
617
|
-
// than the file decides. A document served at `/` is the site's front page,
|
|
618
|
-
// and the front page is the one place a theme may lay a page out differently.
|
|
619
|
-
const page = representation === 'html'
|
|
620
|
-
? c.var.renderer.renderPage(document, {
|
|
621
|
-
frontPage: href === '/',
|
|
622
|
-
extra: { ...commentNotice(c, document, viewer), ...(listed ? {} : { noindex: true }) },
|
|
623
|
-
viewer,
|
|
624
|
-
})
|
|
625
|
-
: undefined;
|
|
626
|
-
const markdown = representation === 'markdown' || representation === 'text'
|
|
627
|
-
? documentMarkdown(document)
|
|
628
|
-
: undefined;
|
|
629
|
-
const body = markdown ??
|
|
630
|
-
(representation === 'json'
|
|
631
|
-
? documentJson(document, { baseUrl: c.var.config.baseUrl })
|
|
632
|
-
: page?.html);
|
|
633
|
-
const response = representationResponse({
|
|
634
|
-
body,
|
|
635
|
-
representation,
|
|
636
|
-
href: encodePath(href),
|
|
637
|
-
available: DOCUMENT_REPRESENTATIONS,
|
|
638
|
-
noindex: !listed,
|
|
639
|
-
// Where a webmention about this page is sent. It is a header rather than
|
|
640
|
-
// only a `<link>` because a sender is allowed to find the endpoint without
|
|
641
|
-
// parsing the page, and because the JSON and Markdown representations of a
|
|
642
|
-
// post have no head to put one in (TASK-51).
|
|
643
|
-
links: webmentionLinks(c),
|
|
644
|
-
// A page drawn for one named reader is that reader's page rather than the
|
|
645
|
-
// post, so nothing shared may hold it and it carries no validator. A page
|
|
646
|
-
// drawn for everybody is exactly what it has always been.
|
|
647
|
-
...(viewer === undefined ? {} : { private: true }),
|
|
648
|
-
// The JSON is the file, so the file's hash and dates validate it. The HTML
|
|
649
|
-
// also draws the theme, the conversation, the neighbours and whatever else
|
|
650
|
-
// the site holds, none of which the file's hash sees, so it is validated by
|
|
651
|
-
// the page it drew (TASK-181). Nothing records when a withdrawn reply
|
|
652
|
-
// stopped being shown, so the HTML has no date that could agree with that
|
|
653
|
-
// ETag and carries no Last-Modified.
|
|
654
|
-
...(page === undefined
|
|
655
|
-
? {
|
|
656
|
-
etag: representationEtag(representation, markdown ?? document.hash),
|
|
657
|
-
lastModified: lastModifiedOf(document),
|
|
658
|
-
}
|
|
659
|
-
: { etag: representationEtag(representation, page.fingerprint) }),
|
|
660
|
-
conditional: conditionalHeaders(c),
|
|
661
|
-
});
|
|
662
|
-
const pingback = pingbackEndpointFor(c.var.renderer.site(), document, c.var.config.now());
|
|
663
|
-
if (pingback !== undefined) {
|
|
664
|
-
response.headers.set('x-pingback', absoluteUrl(pingback, c.var.config.baseUrl));
|
|
665
|
-
}
|
|
666
|
-
return response;
|
|
667
|
-
}
|
|
668
|
-
/**
|
|
669
|
-
* The `Link` header advertising this site's webmention endpoint, or none when
|
|
670
|
-
* the site does not take them.
|
|
671
|
-
*
|
|
672
|
-
* Read per request off the settings, so turning webmentions off on the
|
|
673
|
-
* settings screen takes the advertisement off the very next page rather than
|
|
674
|
-
* off the next restart.
|
|
675
|
-
*/
|
|
676
|
-
function webmentionLinks(c) {
|
|
677
|
-
if (!readSiteSettings(c.var.config.contentDir).webmentionsReceive)
|
|
678
|
-
return [];
|
|
679
|
-
return [`<${WEBMENTION_PATH}>; rel="webmention"`];
|
|
680
|
-
}
|
|
681
|
-
/** The conditional request headers, as the negotiator wants them. */
|
|
682
|
-
function conditionalHeaders(c) {
|
|
683
|
-
return {
|
|
684
|
-
ifNoneMatch: c.req.header('if-none-match'),
|
|
685
|
-
ifModifiedSince: c.req.header('if-modified-since'),
|
|
686
|
-
};
|
|
687
|
-
}
|
|
688
|
-
/**
|
|
689
|
-
* The canonical URL for a path that arrived without its trailing slash, or
|
|
690
|
-
* `undefined` when adding one would not resolve either.
|
|
691
|
-
*
|
|
692
|
-
* Redirecting only to somewhere real means a genuinely missing URL costs one
|
|
693
|
-
* 404 rather than a redirect and then a 404. The target is the canonical URL
|
|
694
|
-
* itself rather than the path with a slash bolted on, so `/page/1` lands on
|
|
695
|
-
* `/` in one hop instead of two.
|
|
696
|
-
*/
|
|
697
|
-
function canonicalPath(c, pathname, bases, authors) {
|
|
698
|
-
if (pathname === '' || pathname.endsWith('/'))
|
|
699
|
-
return undefined;
|
|
700
|
-
const target = canonicalTarget(c, `${pathname}/`, bases, authors);
|
|
701
|
-
if (target === undefined)
|
|
702
|
-
return undefined;
|
|
703
|
-
return `${target}${new URL(c.req.url).search}`;
|
|
704
|
-
}
|
|
705
|
-
/** Where a path with a trailing slash canonically lives, if anywhere. */
|
|
706
|
-
function canonicalTarget(c, pathname, bases, authors) {
|
|
707
|
-
const { store, renderer } = c.var;
|
|
708
|
-
// A feed first: `/feed`, `/feed/atom`, `/{base}/x/feed`, `/comments/feed`
|
|
709
|
-
// and a document's `{permalink}feed` all lead somewhere real, and `/feed/rss`
|
|
710
|
-
// leads to `/feed/` in the same one hop rather than to a second redirect.
|
|
711
|
-
const feedRequest = parseFeedPath(c, pathname, bases, authors);
|
|
712
|
-
if (feedRequest !== undefined) {
|
|
713
|
-
return feedTargetHref(feedRequest.target, feedRequest.format, bases);
|
|
714
|
-
}
|
|
715
|
-
const pages = frontPages(c);
|
|
716
|
-
const document = store.getByPermalink(pathname);
|
|
717
|
-
if (document !== undefined) {
|
|
718
|
-
if (!isServed(document))
|
|
719
|
-
return undefined;
|
|
720
|
-
// The homepage's own URL leads to `/` rather than to the redirect that
|
|
721
|
-
// leads to `/`: one hop, the way `/page/1` reaches `/` in one.
|
|
722
|
-
return document.path === pages.home?.path ? '/' : encodePath(pathname);
|
|
723
|
-
}
|
|
724
|
-
const moved = movedHref(store, pages, pathname, undefined);
|
|
725
|
-
if (moved !== undefined)
|
|
726
|
-
return moved;
|
|
727
|
-
const listing = listingRequestAt(store, pages, pathname, bases, authors);
|
|
728
|
-
if (listing === undefined)
|
|
729
|
-
return undefined;
|
|
730
|
-
const total = countListing(store, listing);
|
|
731
|
-
const totalPages = Math.max(1, Math.ceil(total / renderer.pageSize()));
|
|
732
|
-
if (listing.pageNumber >= totalPages)
|
|
733
|
-
return undefined;
|
|
734
|
-
return listingHref(listing, listing.pageNumber, bases, listing.document?.permalink ?? '/');
|
|
735
|
-
}
|
|
736
|
-
/** {@link AuthorLookup} over one request's site. */
|
|
737
|
-
function authorsOf(c) {
|
|
738
|
-
let users;
|
|
739
|
-
return (username) => {
|
|
740
|
-
users ??= listUsers(c.var.config.dataDir);
|
|
741
|
-
const user = users.find((candidate) => candidate.username === username);
|
|
742
|
-
return user === undefined ? undefined : { user, names: authorNames(users, user) };
|
|
743
|
-
};
|
|
744
|
-
}
|
|
745
|
-
/**
|
|
746
|
-
* WordPress's Reading choice, resolved for this request.
|
|
747
|
-
*
|
|
748
|
-
* The setting holds slugs, and a slug is only a front page while it names a
|
|
749
|
-
* page the public site would serve: one drafted, trashed or deleted since it
|
|
750
|
-
* was picked resolves to nothing, and a site whose homepage resolves to
|
|
751
|
-
* nothing is a site showing its latest posts again. That is the whole of the
|
|
752
|
-
* fallback — there is no state to repair and nothing to write — and it is why
|
|
753
|
-
* the pick is kept rather than cleared: publishing the page again puts the
|
|
754
|
-
* front page back.
|
|
755
|
-
*/
|
|
756
|
-
function frontPages(c) {
|
|
757
|
-
const { homepage, postsPage } = c.var.renderer.frontPageSlugs();
|
|
758
|
-
const home = publicPage(c, homepage);
|
|
759
|
-
return {
|
|
760
|
-
home,
|
|
761
|
-
// Without a homepage there is no posts page: the listing is already at
|
|
762
|
-
// `/`, and a second URL for it is exactly what this pair exists to avoid.
|
|
763
|
-
posts: home === undefined ? undefined : publicPage(c, postsPage),
|
|
764
|
-
};
|
|
765
|
-
}
|
|
766
|
-
/**
|
|
767
|
-
* A path as the page of a listing it names, wherever the listing lives, or
|
|
768
|
-
* `undefined` when it names none.
|
|
769
|
-
*
|
|
770
|
-
* The posts page first, because its permalink is the listing's root on a site
|
|
771
|
-
* that has one; then the ordinary `/`, `/page/N/` and the taxonomy archives.
|
|
772
|
-
* A site whose homepage is a page and which named no posts page has no home
|
|
773
|
-
* listing at all, so nothing under the root is one either.
|
|
774
|
-
*/
|
|
775
|
-
function listingRequestAt(store, pages, pathname, bases, authors) {
|
|
776
|
-
const onPostsPage = pages.posts === undefined ? undefined : postsPageRequest(pages.posts, pathname);
|
|
777
|
-
if (onPostsPage !== undefined)
|
|
778
|
-
return onPostsPage;
|
|
779
|
-
const request = parseListingPath(store, pathname, bases, authors);
|
|
780
|
-
if (request === undefined)
|
|
781
|
-
return undefined;
|
|
782
|
-
// Only the home listing can be homeless. A tag archive and a person's
|
|
783
|
-
// archive have URLs of their own, whatever the Reading setting says `/` is.
|
|
784
|
-
if (request.term === undefined && request.author === undefined) {
|
|
785
|
-
if (listingRoot(pages) === undefined)
|
|
786
|
-
return undefined;
|
|
787
|
-
}
|
|
788
|
-
return request;
|
|
789
|
-
}
|
|
790
|
-
/**
|
|
791
|
-
* Where the post listing lives, or `undefined` when it has no page at all.
|
|
792
|
-
*
|
|
793
|
-
* A site showing its latest posts has it at `/`; a site with a posts page has
|
|
794
|
-
* it there; a site whose homepage is a page and which named no posts page has
|
|
795
|
-
* nowhere for it, which is WordPress's own answer and the reason its Reading
|
|
796
|
-
* screen offers the second pick. The feeds are unaffected either way.
|
|
797
|
-
*/
|
|
798
|
-
function listingRoot(pages) {
|
|
799
|
-
if (pages.posts !== undefined)
|
|
800
|
-
return pages.posts.permalink;
|
|
801
|
-
return pages.home === undefined ? '/' : undefined;
|
|
802
|
-
}
|
|
803
|
-
/** The published page one slug names, or `undefined`. */
|
|
804
|
-
function publicPage(c, slug) {
|
|
805
|
-
if (slug === '')
|
|
806
|
-
return undefined;
|
|
807
|
-
const found = c.var.store.getBySlug(slug);
|
|
808
|
-
if (found?.type !== 'page')
|
|
809
|
-
return undefined;
|
|
810
|
-
return isServed(found, c.var.store.now()) ? found : undefined;
|
|
811
|
-
}
|
|
812
|
-
/**
|
|
813
|
-
* `{permalink}` or `{permalink}page/N/` as a page of the listing the posts
|
|
814
|
-
* page carries, or `undefined` when the path is neither.
|
|
815
|
-
*
|
|
816
|
-
* `page/1/` is not one: the first page of a listing lives at the listing's own
|
|
817
|
-
* URL, exactly as `/page/1/` collapses onto `/`, and the canonicalisation that
|
|
818
|
-
* says so is the ordinary one.
|
|
819
|
-
*/
|
|
820
|
-
function postsPageRequest(document, pathname) {
|
|
821
|
-
const { permalink } = document;
|
|
822
|
-
if (pathname === permalink)
|
|
823
|
-
return { term: undefined, pageNumber: 0, document };
|
|
824
|
-
if (!pathname.startsWith(permalink))
|
|
825
|
-
return undefined;
|
|
826
|
-
const segments = pathname
|
|
827
|
-
.slice(permalink.length)
|
|
828
|
-
.split('/')
|
|
829
|
-
.filter((segment) => segment !== '');
|
|
830
|
-
if (segments.length !== 2 || segments[0] !== PAGE_SEGMENT || !pathname.endsWith('/')) {
|
|
831
|
-
return undefined;
|
|
832
|
-
}
|
|
833
|
-
const page = pageIndex(segments[1]);
|
|
834
|
-
return page === undefined ? undefined : { term: undefined, pageNumber: page, document };
|
|
835
|
-
}
|
|
836
|
-
/**
|
|
837
|
-
* `/`, `/page/N/`, `/author/{username}/` and `/author/{username}/page/N/`, and
|
|
838
|
-
* either taxonomy's `/{base}/x/` and `/{base}/x/page/N/`, as a listing to
|
|
839
|
-
* check.
|
|
840
|
-
*/
|
|
841
|
-
function parseListingPath(store, pathname, bases, authors) {
|
|
842
|
-
const segments = pathname.split('/').filter((segment) => segment !== '');
|
|
843
|
-
if (segments.length === 0)
|
|
844
|
-
return { term: undefined, pageNumber: 0 };
|
|
845
|
-
if (segments[0] === PAGE_SEGMENT && segments.length === 2) {
|
|
846
|
-
const page = pageIndex(segments[1]);
|
|
847
|
-
return page === undefined ? undefined : { term: undefined, pageNumber: page };
|
|
848
|
-
}
|
|
849
|
-
// One person's archive, at the path decision-14 reserves. A username nobody
|
|
850
|
-
// has is not a listing at all, which is what turns it into one 404 rather
|
|
851
|
-
// than an empty archive.
|
|
852
|
-
const byAuthor = parseAuthorPath(pathname);
|
|
853
|
-
if (byAuthor !== undefined) {
|
|
854
|
-
const found = authors(byAuthor.username);
|
|
855
|
-
return found === undefined ? undefined : { author: found, pageNumber: byAuthor.pageNumber };
|
|
856
|
-
}
|
|
857
|
-
// A taxonomy archive exists only while a published post carries the term,
|
|
858
|
-
// so a term nothing carries is not a listing, whatever its path says.
|
|
859
|
-
const asked = parseTermPath(pathname, bases);
|
|
860
|
-
if (asked === undefined)
|
|
861
|
-
return undefined;
|
|
862
|
-
const spelled = carriedSpelling(store, asked.term);
|
|
863
|
-
return spelled === undefined
|
|
864
|
-
? undefined
|
|
865
|
-
: { term: { ...asked.term, term: spelled }, pageNumber: asked.pageNumber };
|
|
866
|
-
}
|
|
867
|
-
/**
|
|
868
|
-
* `/{base}/x/` and `/{base}/x/page/N/` as the term and page they name, as the
|
|
869
|
-
* path spells them, whether or not anything carries the term.
|
|
870
|
-
*/
|
|
871
|
-
function parseTermPath(pathname, bases) {
|
|
872
|
-
const segments = pathname.split('/').filter((segment) => segment !== '');
|
|
873
|
-
const taxonomy = taxonomyForSegment(segments[0], bases);
|
|
874
|
-
const named = segments[1];
|
|
875
|
-
if (taxonomy === undefined || named === undefined)
|
|
876
|
-
return undefined;
|
|
877
|
-
const term = { taxonomy, term: named };
|
|
878
|
-
if (segments.length === 2)
|
|
879
|
-
return { term, pageNumber: 0 };
|
|
880
|
-
if (segments.length === 4 && segments[2] === PAGE_SEGMENT) {
|
|
881
|
-
const page = pageIndex(segments[3]);
|
|
882
|
-
return page === undefined ? undefined : { term, pageNumber: page };
|
|
883
|
-
}
|
|
884
|
-
return undefined;
|
|
885
|
-
}
|
|
886
|
-
/**
|
|
887
|
-
* How the site spells a term some published post carries, matched without
|
|
888
|
-
* regard to case, or `undefined` when none carries it (TASK-339).
|
|
889
|
-
*
|
|
890
|
-
* A tag's casings are one term (TASK-308). A category stays as spelled, so a
|
|
891
|
-
* category carried in exactly the asked spelling wins, and otherwise the most
|
|
892
|
-
* used one that differs only in case: WordPress lower-cased every slug, so an
|
|
893
|
-
* imported `/category/rsscloud/` names the category spelled `rssCloud`.
|
|
894
|
-
*/
|
|
895
|
-
function carriedSpelling(store, term) {
|
|
896
|
-
if (term.taxonomy === 'tag') {
|
|
897
|
-
return store.countByTag(term.term) > 0 ? store.tagSpelling(term.term) : undefined;
|
|
898
|
-
}
|
|
899
|
-
if (store.countByCategory(term.term) > 0)
|
|
900
|
-
return term.term;
|
|
901
|
-
const key = term.term.toLowerCase();
|
|
902
|
-
return store.listCategories().find(({ category }) => category.toLowerCase() === key)?.category;
|
|
903
|
-
}
|
|
904
|
-
/** How many published documents a listing holds. */
|
|
905
|
-
function countListing(store, subject) {
|
|
906
|
-
const { term, author } = subject;
|
|
907
|
-
if (author !== undefined)
|
|
908
|
-
return store.countByAuthor(author.names);
|
|
909
|
-
if (term === undefined)
|
|
910
|
-
return store.counts().posts;
|
|
911
|
-
return term.taxonomy === 'tag' ? store.countByTag(term.term) : store.countByCategory(term.term);
|
|
912
|
-
}
|
|
913
|
-
/** One page of a listing's documents, newest first. */
|
|
914
|
-
function listListing(store, subject, paging) {
|
|
915
|
-
const { term, author } = subject;
|
|
916
|
-
if (author !== undefined)
|
|
917
|
-
return store.listByAuthor(author.names, paging);
|
|
918
|
-
if (term === undefined)
|
|
919
|
-
return store.listPosts(paging);
|
|
920
|
-
return term.taxonomy === 'tag'
|
|
921
|
-
? store.listByTag(term.term, paging)
|
|
922
|
-
: store.listByCategory(term.term, paging);
|
|
923
|
-
}
|
|
924
|
-
/**
|
|
925
|
-
* The URL of a page of a listing: the home archive's, or a taxonomy's.
|
|
926
|
-
*
|
|
927
|
-
* `root` is where the home listing lives — `/`, or the posts page's permalink
|
|
928
|
-
* on a site that has one — so every link the listing draws, every canonical
|
|
929
|
-
* redirect and the sitemap all spell its pages the same way.
|
|
930
|
-
*/
|
|
931
|
-
function listingHref(subject, index, bases, root = '/') {
|
|
932
|
-
const { term, author } = subject;
|
|
933
|
-
if (author !== undefined)
|
|
934
|
-
return authorHref(author.user.username, index);
|
|
935
|
-
return term === undefined ? listingPageHref(root, index) : termHref(term, index, bases);
|
|
936
|
-
}
|
|
937
|
-
/**
|
|
938
|
-
* The URL of one format of one listing's feed, whichever kind of listing it is.
|
|
939
|
-
*
|
|
940
|
-
* The site's and a taxonomy's hang off the listing root; a person's hangs off
|
|
941
|
-
* their archive, which decision-14 keeps at WordPress's `/author/{username}/`
|
|
942
|
-
* rather than under the listing machinery, because that root is also an actor
|
|
943
|
-
* id.
|
|
944
|
-
*/
|
|
945
|
-
function listingFeedHref(subject, format, bases) {
|
|
946
|
-
return subject.author === undefined
|
|
947
|
-
? feedHref(subject.term, format, bases)
|
|
948
|
-
: authorFeedHref(subject.author.user.username, format);
|
|
949
|
-
}
|
|
950
|
-
/**
|
|
951
|
-
* A `/page/N/` segment as a zero-based index. `page/1` parses to the first
|
|
952
|
-
* page, which lives at the listing root, so canonicalisation collapses it.
|
|
953
|
-
*/
|
|
954
|
-
function pageIndex(segment) {
|
|
955
|
-
if (segment === undefined || !/^[0-9]+$/.test(segment))
|
|
956
|
-
return undefined;
|
|
957
|
-
const requested = Number(segment);
|
|
958
|
-
return requested < 1 ? undefined : requested - 1;
|
|
959
|
-
}
|
|
960
|
-
/** One page of a listing, in whichever representation the request settled on. */
|
|
961
|
-
function listing(c, request, representation = selectFromAccept(c, LISTING_REPRESENTATIONS)) {
|
|
962
|
-
const { store, renderer } = c.var;
|
|
963
|
-
const { term, author } = request;
|
|
964
|
-
const size = renderer.pageSize();
|
|
965
|
-
const bases = renderer.taxonomyBases();
|
|
966
|
-
// Where this listing's pages live: the posts page's permalink when the site
|
|
967
|
-
// has one, and the site root otherwise.
|
|
968
|
-
const root = request.document?.permalink ?? '/';
|
|
969
|
-
// WordPress served every feed as a query on the listing before it served one
|
|
970
|
-
// at a path, and the links are still out there. `/?feed=rss2` and
|
|
971
|
-
// `/{base}/x/?feed=atom` land on the feed the listing now has.
|
|
972
|
-
const asked = queryFeedFormat(c);
|
|
973
|
-
if (asked !== undefined)
|
|
974
|
-
return c.redirect(listingFeedHref(request, asked, bases), 301);
|
|
975
|
-
const total = countListing(store, request);
|
|
976
|
-
const href = listingHref(request, request.pageNumber, bases, root);
|
|
977
|
-
const pagination = paginate({
|
|
978
|
-
total,
|
|
979
|
-
size,
|
|
980
|
-
pageNumber: request.pageNumber,
|
|
981
|
-
hrefForPage: (index) => listingHref(request, index, bases, root),
|
|
982
|
-
});
|
|
983
|
-
if (request.pageNumber >= pagination.totalPages)
|
|
984
|
-
return notFound(c);
|
|
985
|
-
if (representation === undefined)
|
|
986
|
-
return notAcceptableResponse(href, LISTING_REPRESENTATIONS);
|
|
987
|
-
const paging = { limit: size, offset: offsetForPage(request.pageNumber, size) };
|
|
988
|
-
const documents = listListing(store, request, paging);
|
|
989
|
-
const title = term?.term ??
|
|
990
|
-
author?.user.profile?.displayName ??
|
|
991
|
-
author?.user.username ??
|
|
992
|
-
request.document?.title ??
|
|
993
|
-
renderer.site().title;
|
|
994
|
-
if (representation === 'markdown' || representation === 'text') {
|
|
995
|
-
return listingMarkdown(c, request, representation, { href, title, pagination, documents });
|
|
996
|
-
}
|
|
997
|
-
const full = wantsFullDocuments(c);
|
|
998
|
-
const body = representation === 'json'
|
|
999
|
-
? documents.map((document) => documentJson(document, { baseUrl: c.var.config.baseUrl, body: full }))
|
|
1000
|
-
: renderer.renderListing({
|
|
1001
|
-
title,
|
|
1002
|
-
url: href,
|
|
1003
|
-
documents,
|
|
1004
|
-
pagination,
|
|
1005
|
-
// And its words go above the posts, which is what a posts page is
|
|
1006
|
-
// for: a theme prints `{{ content | safe }}` over the list.
|
|
1007
|
-
...(request.document === undefined ? {} : { document: request.document }),
|
|
1008
|
-
...(term === undefined ? {} : taxonomyContext(term)),
|
|
1009
|
-
...(author === undefined ? {} : authorArchiveContext(author)),
|
|
1010
|
-
});
|
|
1011
|
-
const validated = representation !== 'html' || !c.var.config.watch;
|
|
1012
|
-
return representationResponse({
|
|
1013
|
-
body,
|
|
1014
|
-
representation,
|
|
1015
|
-
href,
|
|
1016
|
-
available: LISTING_REPRESENTATIONS,
|
|
1017
|
-
...(drawnForSomebody(c, representation) ? { private: true } : {}),
|
|
1018
|
-
...(validated
|
|
1019
|
-
? {
|
|
1020
|
-
etag: representationEtag(representation, listingFingerprint(href, pagination, documents, full)),
|
|
1021
|
-
lastModified: latestModified(documents),
|
|
1022
|
-
}
|
|
1023
|
-
: {}),
|
|
1024
|
-
conditional: conditionalHeaders(c),
|
|
1025
|
-
});
|
|
1026
|
-
}
|
|
1027
|
-
function listingMarkdown(c, request, representation, page) {
|
|
1028
|
-
const { next, previous } = page.pagination.href;
|
|
1029
|
-
const home = frontPages(c).home;
|
|
1030
|
-
const latestPosts = request.term === undefined && request.author === undefined;
|
|
1031
|
-
const description = request.document?.description ?? (latestPosts ? c.var.renderer.site().tagline : undefined);
|
|
1032
|
-
const body = llmsListingTxt({
|
|
1033
|
-
title: page.title,
|
|
1034
|
-
description,
|
|
1035
|
-
posts: page.documents.map((document) => llmsEntry(c, document, home)),
|
|
1036
|
-
newer: previous === null ? undefined : representationHref(previous, 'markdown'),
|
|
1037
|
-
older: next === null ? undefined : representationHref(next, 'markdown'),
|
|
1038
|
-
}, c.var.config.baseUrl);
|
|
1039
|
-
return representationResponse({
|
|
1040
|
-
body,
|
|
1041
|
-
representation,
|
|
1042
|
-
href: page.href,
|
|
1043
|
-
available: LISTING_REPRESENTATIONS,
|
|
1044
|
-
etag: representationEtag(representation, body),
|
|
1045
|
-
lastModified: latestModified(page.documents),
|
|
1046
|
-
conditional: conditionalHeaders(c),
|
|
1047
|
-
});
|
|
1048
|
-
}
|
|
1049
|
-
function documentMarkdown(document) {
|
|
1050
|
-
const title = document.title.replace(/\s+/g, ' ').trim();
|
|
1051
|
-
if (title === '' || /^#[ \t]/.test(document.body.trimStart()))
|
|
1052
|
-
return serializeDocument(document);
|
|
1053
|
-
return serializeDocument({ ...document, body: `# ${title}\n\n${document.body}` });
|
|
1054
|
-
}
|
|
1055
|
-
/**
|
|
1056
|
-
* One page of search results, in whichever representation the request settled
|
|
1057
|
-
* on.
|
|
1058
|
-
*
|
|
1059
|
-
* What it finds is what the listings would show: the index holds the search to
|
|
1060
|
-
* published, untrashed, already-due documents, so a draft cannot be found by
|
|
1061
|
-
* its words any more than it can be found by its URL. A search with no query
|
|
1062
|
-
* is the page with the form on it and nothing found, rather than an error,
|
|
1063
|
-
* because that is where a link to the search from a theme lands. A page past
|
|
1064
|
-
* the last one 404s, as it does on a listing.
|
|
1065
|
-
*/
|
|
1066
|
-
function search(c, representation) {
|
|
1067
|
-
const { store, renderer, config } = c.var;
|
|
1068
|
-
const query = searchQuery(c.req.query(SEARCH_QUERY_PARAM));
|
|
1069
|
-
const pageNumber = searchPageIndex(c.req.query(SEARCH_PAGE_PARAM));
|
|
1070
|
-
if (pageNumber === undefined)
|
|
1071
|
-
return notFound(c);
|
|
1072
|
-
const size = renderer.pageSize();
|
|
1073
|
-
const pagination = paginate({
|
|
1074
|
-
total: store.countSearch(query),
|
|
1075
|
-
size,
|
|
1076
|
-
pageNumber,
|
|
1077
|
-
hrefForPage: (index) => searchHref(query, index),
|
|
1078
|
-
});
|
|
1079
|
-
if (pageNumber >= pagination.totalPages)
|
|
1080
|
-
return notFound(c);
|
|
1081
|
-
const href = searchHref(query, pageNumber);
|
|
1082
|
-
if (representation === undefined)
|
|
1083
|
-
return notAcceptableResponse(href, SEARCH_REPRESENTATIONS);
|
|
1084
|
-
const hits = store.search(query, { limit: size, offset: offsetForPage(pageNumber, size) });
|
|
1085
|
-
const documents = hits.map((hit) => hit.document);
|
|
1086
|
-
const full = wantsFullDocuments(c);
|
|
1087
|
-
const body = representation === 'json'
|
|
1088
|
-
? searchJson({ query, hits, pagination, baseUrl: config.baseUrl, body: full })
|
|
1089
|
-
: renderer.renderSearch({ query, url: href, hits, pagination });
|
|
1090
|
-
const validated = representation !== 'html' || !config.watch;
|
|
1091
|
-
return representationResponse({
|
|
1092
|
-
body,
|
|
1093
|
-
representation,
|
|
1094
|
-
href,
|
|
1095
|
-
// The alternates are spelled here rather than by the negotiator, because
|
|
1096
|
-
// they carry the query and a listing's never have one to carry.
|
|
1097
|
-
available: [representation],
|
|
1098
|
-
links: SEARCH_REPRESENTATIONS.filter((other) => other !== representation).map((other) => `<${searchHref(query, pageNumber, other)}>; rel="alternate"; type="${MEDIA_TYPES[other]}"`),
|
|
1099
|
-
...(drawnForSomebody(c, representation) ? { private: true } : {}),
|
|
1100
|
-
...(validated
|
|
1101
|
-
? {
|
|
1102
|
-
etag: representationEtag(representation, listingFingerprint(href, pagination, documents, full)),
|
|
1103
|
-
lastModified: latestModified(documents),
|
|
1104
|
-
}
|
|
1105
|
-
: {}),
|
|
1106
|
-
conditional: conditionalHeaders(c),
|
|
1107
|
-
});
|
|
1108
|
-
}
|
|
1109
|
-
/**
|
|
1110
|
-
* Whether this is a page drawn for a signed-in reader, which carries the admin
|
|
1111
|
-
* bar (TASK-183) and so must never be answered with a 304 off the validators of
|
|
1112
|
-
* the copy an anonymous visit left in their browser.
|
|
1113
|
-
*/
|
|
1114
|
-
function drawnForSomebody(c, representation) {
|
|
1115
|
-
return representation === 'html' && c.var.signedIn !== undefined;
|
|
1116
|
-
}
|
|
1117
|
-
/**
|
|
1118
|
-
* Whether the request asked for whole documents rather than summaries.
|
|
1119
|
-
*
|
|
1120
|
-
* Anything but an explicit denial counts, so `?full`, `?full=1` and `?full=yes`
|
|
1121
|
-
* all mean the same thing to someone typing a URL by hand.
|
|
1122
|
-
*/
|
|
1123
|
-
function wantsFullDocuments(c) {
|
|
1124
|
-
const value = c.req.query('full');
|
|
1125
|
-
return value !== undefined && value !== '0' && value.toLowerCase() !== 'false';
|
|
1126
|
-
}
|
|
1127
|
-
/**
|
|
1128
|
-
* What a listing page is made of, as one string to hash.
|
|
1129
|
-
*
|
|
1130
|
-
* The documents on the page are not the whole story: the same two posts on a
|
|
1131
|
-
* differently sized archive are a different page, and a summary is not the
|
|
1132
|
-
* body, so the pagination and the `full` flag are in the fingerprint too.
|
|
1133
|
-
*/
|
|
1134
|
-
function listingFingerprint(href, pagination, documents, full) {
|
|
1135
|
-
return [
|
|
1136
|
-
href,
|
|
1137
|
-
`${String(pagination.pageNumber)}/${String(pagination.totalPages)}/${String(pagination.total)}`,
|
|
1138
|
-
full ? 'full' : 'summary',
|
|
1139
|
-
...documents.map((document) => document.hash),
|
|
1140
|
-
].join('\n');
|
|
1141
|
-
}
|
|
1142
|
-
/**
|
|
1143
|
-
* The site's feed, or one archive's, in one format.
|
|
1144
|
-
*
|
|
1145
|
-
* A term with nothing published under it 404s exactly as its archive does: a
|
|
1146
|
-
* feed reader should be told the URL is wrong rather than handed an empty feed
|
|
1147
|
-
* it will poll forever.
|
|
1148
|
-
*/
|
|
1149
|
-
function feed(c, format, subject) {
|
|
1150
|
-
const { store, renderer, config } = c.var;
|
|
1151
|
-
const site = renderer.site();
|
|
1152
|
-
const bases = renderer.taxonomyBases();
|
|
1153
|
-
const { term, author } = subject;
|
|
1154
|
-
const documents = listListing(store, subject, { limit: feedSize(site) });
|
|
1155
|
-
const href = listingHref(subject, 0, bases);
|
|
1156
|
-
// What the feed calls itself: the site, and then the term or the person it
|
|
1157
|
-
// is about, so a reader subscribed to several of a site's feeds can tell
|
|
1158
|
-
// them apart in a list.
|
|
1159
|
-
const about = term?.term ?? author?.user.profile?.displayName ?? author?.user.username;
|
|
1160
|
-
const source = {
|
|
1161
|
-
site,
|
|
1162
|
-
users: listUsers(config.dataDir),
|
|
1163
|
-
documents,
|
|
1164
|
-
title: about === undefined ? site.title : `${site.title}: ${about}`,
|
|
1165
|
-
href,
|
|
1166
|
-
feedHref: listingFeedHref(subject, format, bases),
|
|
1167
|
-
baseUrl: config.baseUrl,
|
|
1168
|
-
// Only RSS carries the comment pointers; the other two formats have no
|
|
1169
|
-
// vocabulary for them, and counting for a feed that cannot say the number
|
|
1170
|
-
// would be a query per item for nothing.
|
|
1171
|
-
...(format === 'rss' ? { commentCounts: c.var.conversation.counts(documents) } : {}),
|
|
1172
|
-
altTexts: readAltTexts(config.contentDir),
|
|
1173
|
-
replyContext: (target) => c.var.replyContexts.read(target),
|
|
1174
|
-
};
|
|
1175
|
-
return feedResponse({ format, source, conditional: conditionalHeaders(c) });
|
|
1176
|
-
}
|
|
1177
|
-
/**
|
|
1178
|
-
* A post's or page's comments, or the whole site's, as RSS 2.0.
|
|
1179
|
-
*
|
|
1180
|
-
* A document with no replies answers an empty feed rather than a 404: it
|
|
1181
|
-
* exists, and a reader that subscribed before anybody answered should keep
|
|
1182
|
-
* polling. Which documents have a feed at all is {@link parseFeedPath}'s to say.
|
|
1183
|
-
*/
|
|
1184
|
-
function comments(c, document) {
|
|
1185
|
-
const { conversation, renderer, config } = c.var;
|
|
1186
|
-
const site = renderer.site();
|
|
1187
|
-
const limit = feedSize(site);
|
|
1188
|
-
// The same reading the page is drawn from, which is the point: a subscriber
|
|
1189
|
-
// to a post's comments and a reader who scrolls to the bottom of it are
|
|
1190
|
-
// looking at one conversation. A post's own feed hands the builder entries
|
|
1191
|
-
// with no post attached, and so its items name no post: there, every item
|
|
1192
|
-
// answers the same one.
|
|
1193
|
-
const found = feedComments(document === undefined ? conversation.latest(limit) : spokenIn(conversation.thread(document)), {
|
|
1194
|
-
baseUrl: config.baseUrl,
|
|
1195
|
-
limit,
|
|
1196
|
-
cited: (url) => c.var.replyContexts.read(url),
|
|
1197
|
-
post: document,
|
|
1198
|
-
});
|
|
1199
|
-
const source = {
|
|
1200
|
-
site,
|
|
1201
|
-
comments: found,
|
|
1202
|
-
title: document === undefined
|
|
1203
|
-
? `${site.title}: comments`
|
|
1204
|
-
: `${COMMENTS_TITLE_PREFIX}${postLabel(document, (url) => c.var.replyContexts.read(url))}`,
|
|
1205
|
-
href: document?.permalink ?? '/',
|
|
1206
|
-
feedHref: commentsFeedHref(document),
|
|
1207
|
-
baseUrl: config.baseUrl,
|
|
1208
|
-
};
|
|
1209
|
-
return commentsFeedResponse(source, conditionalHeaders(c));
|
|
1210
|
-
}
|
|
1211
|
-
/**
|
|
1212
|
-
* The feed of one item's direct replies (TASK-324): a post's or page's, or a
|
|
1213
|
-
* reply's, so a reader can walk a thread one level at a time through
|
|
1214
|
-
* `source:comments`. An item nobody answered has an empty feed; a segment
|
|
1215
|
-
* naming nothing a reader can see 404s, as does one on a document not showing
|
|
1216
|
-
* its conversation, by the rule `{permalink}feed/` follows.
|
|
1217
|
-
*/
|
|
1218
|
-
function repliesFeed(c, segment) {
|
|
1219
|
-
const { conversation, renderer, config } = c.var;
|
|
1220
|
-
const found = conversation.repliesTo(segment);
|
|
1221
|
-
if (found === undefined || !showsConversation(c, found.post))
|
|
1222
|
-
return notFound(c);
|
|
1223
|
-
const site = renderer.site();
|
|
1224
|
-
const cited = (url) => c.var.replyContexts.read(url);
|
|
1225
|
-
const label = postLabel(found.post, cited);
|
|
1226
|
-
const source = {
|
|
1227
|
-
site,
|
|
1228
|
-
comments: feedComments(found.replies, {
|
|
1229
|
-
baseUrl: config.baseUrl,
|
|
1230
|
-
limit: feedSize(site),
|
|
1231
|
-
cited,
|
|
1232
|
-
post: found.post,
|
|
1233
|
-
}),
|
|
1234
|
-
title: found.reply === null
|
|
1235
|
-
? `Replies to: ${label}`
|
|
1236
|
-
: `Replies to ${found.reply.author.name} on ${label}`,
|
|
1237
|
-
href: found.reply?.url ?? found.post.permalink,
|
|
1238
|
-
feedHref: repliesFeedPath(segment),
|
|
1239
|
-
baseUrl: config.baseUrl,
|
|
1240
|
-
};
|
|
1241
|
-
return commentsFeedResponse(source, conditionalHeaders(c));
|
|
1242
|
-
}
|
|
1243
|
-
/**
|
|
1244
|
-
* One native comment on a page of its own (TASK-318), answering as its post
|
|
1245
|
-
* would: 410 once the post is deleted, and 404 while it is not served or not
|
|
1246
|
-
* showing its conversation. It is never listed anywhere, so it is noindex.
|
|
1247
|
-
*/
|
|
1248
|
-
function commentPage(c, id) {
|
|
1249
|
-
const { conversation, renderer, store } = c.var;
|
|
1250
|
-
const found = conversation.comment(id);
|
|
1251
|
-
if (found === undefined)
|
|
1252
|
-
return notFound(c);
|
|
1253
|
-
const now = store.now();
|
|
1254
|
-
if (isGone(found.post, now))
|
|
1255
|
-
return gone(c);
|
|
1256
|
-
if (!isServed(found.post, now) || !showsConversation(c, found.post))
|
|
1257
|
-
return notFound(c);
|
|
1258
|
-
return c.html(renderer.renderComment(found), 200, { 'x-robots-tag': 'noindex' });
|
|
1259
|
-
}
|
|
1260
|
-
/**
|
|
1261
|
-
* The sitemap, or one of its children once the site is too big for one file.
|
|
1262
|
-
*
|
|
1263
|
-
* A child that does not exist 404s through the theme like any other missing
|
|
1264
|
-
* URL: `/sitemap-1.xml` names nothing at all on a site whose whole sitemap
|
|
1265
|
-
* fits, and a crawler asking for one should be told so rather than handed an
|
|
1266
|
-
* empty file it would come back to.
|
|
1267
|
-
*/
|
|
1268
|
-
function sitemap(c, page) {
|
|
1269
|
-
const response = sitemapResponse({
|
|
1270
|
-
urls: sitemapUrls(c),
|
|
1271
|
-
baseUrl: c.var.config.baseUrl,
|
|
1272
|
-
page,
|
|
1273
|
-
conditional: conditionalHeaders(c),
|
|
1274
|
-
});
|
|
1275
|
-
return response ?? notFound(c);
|
|
1276
|
-
}
|
|
1277
|
-
/**
|
|
1278
|
-
* Every URL the public site publishes, in the order the sitemap lists them:
|
|
1279
|
-
* the home archive's pages, then every post and page, then every tag archive
|
|
1280
|
-
* and every category archive with their own pages.
|
|
1281
|
-
*
|
|
1282
|
-
* Everything here is spelled by the same functions the site's own links go
|
|
1283
|
-
* through — {@link homeHref}, the permalinks, {@link termHref} — and drawn
|
|
1284
|
-
* from the same queries the listings use, so a sitemap can never advertise a
|
|
1285
|
-
* URL the site does not serve. Nothing hidden reaches it either: the index's
|
|
1286
|
-
* listing queries already exclude drafts, the trash, posts whose date has not
|
|
1287
|
-
* arrived and unlisted documents, and {@link isListed} is asked again with the
|
|
1288
|
-
* store's own clock so the two answers cannot drift apart.
|
|
1289
|
-
*/
|
|
1290
|
-
function sitemapUrls(c) {
|
|
1291
|
-
const { store, renderer } = c.var;
|
|
1292
|
-
const now = store.now();
|
|
1293
|
-
const size = renderer.pageSize();
|
|
1294
|
-
const bases = renderer.taxonomyBases();
|
|
1295
|
-
const pages = frontPages(c);
|
|
1296
|
-
const urls = [];
|
|
1297
|
-
/** The pages of one listing, each dated by the newest document on it. */
|
|
1298
|
-
const listingPages = (documents, hrefForPage) => {
|
|
1299
|
-
const totalPages = Math.max(1, Math.ceil(documents.length / size));
|
|
1300
|
-
for (let index = 0; index < totalPages; index += 1) {
|
|
1301
|
-
const onPage = documents.slice(index * size, (index + 1) * size);
|
|
1302
|
-
urls.push({ loc: hrefForPage(index), lastmod: latestModified(onPage) });
|
|
1303
|
-
}
|
|
1304
|
-
};
|
|
1305
|
-
const posts = store.listPosts().filter((document) => isListed(document, now));
|
|
1306
|
-
// The listing's pages, wherever it lives: under `/`, under the posts page,
|
|
1307
|
-
// or nowhere at all on a site whose homepage is a page and which named no
|
|
1308
|
-
// posts page. Its first page is that root, which is why `/` and the posts
|
|
1309
|
-
// page's own URL are listed here rather than with the documents.
|
|
1310
|
-
const root = listingRoot(pages);
|
|
1311
|
-
if (root !== undefined)
|
|
1312
|
-
listingPages(posts, (index) => listingPageHref(root, index));
|
|
1313
|
-
// And `/` itself when it is a page rather than the listing: the front page
|
|
1314
|
-
// is published at one URL, and it is this one.
|
|
1315
|
-
if (pages.home !== undefined)
|
|
1316
|
-
urls.push({ loc: '/', lastmod: lastModifiedOf(pages.home) });
|
|
1317
|
-
const documents = store
|
|
1318
|
-
.listAll({ type: 'page', draft: false, trashed: false, scheduled: false })
|
|
1319
|
-
.filter((document) => isListed(document, now));
|
|
1320
|
-
for (const document of [...posts, ...documents]) {
|
|
1321
|
-
// The homepage answers at `/` and redirects from its own permalink, and
|
|
1322
|
-
// the posts page is the listing's first page, which is already listed:
|
|
1323
|
-
// neither is advertised twice.
|
|
1324
|
-
if (document.path === pages.home?.path || document.path === pages.posts?.path)
|
|
1325
|
-
continue;
|
|
1326
|
-
urls.push({ loc: document.permalink, lastmod: lastModifiedOf(document) });
|
|
1327
|
-
}
|
|
1328
|
-
// A taxonomy archive exists only while something public carries the term,
|
|
1329
|
-
// which is exactly what these two queries report.
|
|
1330
|
-
for (const { tag } of store.listTags()) {
|
|
1331
|
-
const term = { taxonomy: 'tag', term: tag };
|
|
1332
|
-
listingPages(store.listByTag(tag), (index) => termHref(term, index, bases));
|
|
1333
|
-
}
|
|
1334
|
-
for (const { category } of store.listCategories()) {
|
|
1335
|
-
const term = { taxonomy: 'category', term: category };
|
|
1336
|
-
listingPages(store.listByCategory(category), (index) => termHref(term, index, bases));
|
|
1337
|
-
}
|
|
1338
|
-
return urls;
|
|
1339
|
-
}
|
|
1340
|
-
/**
|
|
1341
|
-
* What a generated `/llms.txt` lists: every public page by title, then the
|
|
1342
|
-
* posts the feeds carry, newest first, each linked to its Markdown.
|
|
1343
|
-
*
|
|
1344
|
-
* The homepage is listed at `/`, which is where it is published; its own
|
|
1345
|
-
* permalink redirects there.
|
|
1346
|
-
*/
|
|
1347
|
-
function llmsIndex(c) {
|
|
1348
|
-
const { store, renderer } = c.var;
|
|
1349
|
-
const site = renderer.site();
|
|
1350
|
-
const now = store.now();
|
|
1351
|
-
const home = frontPages(c).home;
|
|
1352
|
-
const entry = (document) => llmsEntry(c, document, home);
|
|
1353
|
-
const pages = store
|
|
1354
|
-
.listAll({ type: 'page', draft: false, trashed: false, scheduled: false })
|
|
1355
|
-
.filter((document) => isListed(document, now))
|
|
1356
|
-
.sort((a, b) => llmsLabel(c, a).localeCompare(llmsLabel(c, b)));
|
|
1357
|
-
const posts = store
|
|
1358
|
-
.listPosts({ limit: feedSize(site) })
|
|
1359
|
-
.filter((document) => isListed(document, now));
|
|
1360
|
-
return {
|
|
1361
|
-
title: site.title,
|
|
1362
|
-
description: site.tagline ?? '',
|
|
1363
|
-
pages: pages.map(entry),
|
|
1364
|
-
posts: posts.map(entry),
|
|
1365
|
-
};
|
|
1366
|
-
}
|
|
1367
|
-
function llmsLabel(c, document) {
|
|
1368
|
-
return postLabel(document, (url) => c.var.replyContexts.read(url));
|
|
1369
|
-
}
|
|
1370
|
-
function llmsEntry(c, document, home) {
|
|
1371
|
-
return {
|
|
1372
|
-
title: llmsLabel(c, document),
|
|
1373
|
-
href: representationHref(document.path === home?.path ? '/' : encodePath(document.permalink), 'markdown'),
|
|
1374
|
-
description: document.description,
|
|
1375
|
-
lastModified: lastModifiedOf(document),
|
|
1376
|
-
};
|
|
1377
|
-
}
|
|
1378
|
-
/**
|
|
1379
|
-
* A file from the theme's `static/` directory, the site's copy first.
|
|
1380
|
-
*
|
|
1381
|
-
* Assets are cacheable and validated, so a browser that already has one pays a
|
|
1382
|
-
* conditional request rather than a download. A URL whose `v` is the hash of
|
|
1383
|
-
* the bytes being served, which is what the `asset` filter writes, is cached
|
|
1384
|
-
* for a year without revalidation. Any other `v`, or none, gets the short
|
|
1385
|
-
* lifetime: a stale hash from a cached page still gets the file, but the
|
|
1386
|
-
* current bytes are never pinned under a name that describes older ones.
|
|
1387
|
-
*/
|
|
1388
|
-
function themeAsset(c) {
|
|
1389
|
-
const relative = requestPath(c).slice(THEME_ASSET_PREFIX.length);
|
|
1390
|
-
const asset = findThemeAsset(relative, c.var.renderer.themeDirs());
|
|
1391
|
-
if (asset === undefined)
|
|
1392
|
-
return notFound(c);
|
|
1393
|
-
const fingerprinted = c.req.query(ASSET_VERSION_PARAM) === assetVersion(asset);
|
|
1394
|
-
const options = fingerprinted ? IMMUTABLE_ASSET : {};
|
|
1395
|
-
return matchesEtag(c.req.header('if-none-match'), asset.etag)
|
|
1396
|
-
? assetNotModified(asset, options)
|
|
1397
|
-
: assetResponse(asset, options);
|
|
1398
|
-
}
|
|
1399
|
-
/**
|
|
1400
|
-
* One derived copy of an upload, generated on the spot if it is not there.
|
|
1401
|
-
*
|
|
1402
|
-
* The directory these live in is disposable (decision-9): deleting it costs
|
|
1403
|
-
* the next reader of each picture one encode and costs the site nothing else,
|
|
1404
|
-
* which is what this handler is for. A width or a format the site does not
|
|
1405
|
-
* offer is a 404 and encodes nothing, so the URL space cannot be used to make
|
|
1406
|
-
* the server work.
|
|
1407
|
-
*
|
|
1408
|
-
* A variant is cached for a year without revalidation only when its `v` is
|
|
1409
|
-
* the hash of the upload it was derived from, which is what the page markup
|
|
1410
|
-
* and the icon links write. The name alone cannot promise that: deleting an
|
|
1411
|
-
* upload frees its name for different bytes. Any other `v`, or none, as in a
|
|
1412
|
-
* page cached before URLs carried one, still gets the file, for a day.
|
|
1413
|
-
*/
|
|
1414
|
-
async function imageVariant(c) {
|
|
1415
|
-
const relative = decodeVariantPath(requestPath(c).slice(VARIANT_ASSET_PREFIX.length));
|
|
1416
|
-
const asset = await findImageVariant(c.var.config, relative);
|
|
1417
|
-
if (asset === undefined)
|
|
1418
|
-
return notFound(c);
|
|
1419
|
-
const source = relative.slice(0, relative.lastIndexOf('/'));
|
|
1420
|
-
const version = sourceVersion(c.var.config, source);
|
|
1421
|
-
const fingerprinted = version !== undefined && c.req.query(ASSET_VERSION_PARAM) === version;
|
|
1422
|
-
const options = fingerprinted ? IMMUTABLE_ASSET : { maxAge: UPLOAD_ASSET_MAX_AGE };
|
|
1423
|
-
return matchesEtag(c.req.header('if-none-match'), asset.etag)
|
|
1424
|
-
? assetNotModified(asset, options)
|
|
1425
|
-
: assetResponse(asset, options);
|
|
1426
|
-
}
|
|
1427
|
-
/**
|
|
1428
|
-
* `/favicon.ico`, derived from the site's icon beside its other icons.
|
|
1429
|
-
*
|
|
1430
|
-
* Its URL carries no version, so it is cached like an upload rather than for
|
|
1431
|
-
* a year: a site that changes its icon is seen with the new one within a day.
|
|
1432
|
-
*/
|
|
1433
|
-
async function favicon(c) {
|
|
1434
|
-
const source = siteIconSource(c.var.config, iconSetting(c.var.renderer.site()));
|
|
1435
|
-
if (source === undefined)
|
|
1436
|
-
return notFound(c);
|
|
1437
|
-
const asset = await findImageVariant(c.var.config, `${source}/${FAVICON_FILE}`);
|
|
1438
|
-
if (asset === undefined)
|
|
1439
|
-
return notFound(c);
|
|
1440
|
-
const options = { maxAge: UPLOAD_ASSET_MAX_AGE };
|
|
1441
|
-
return matchesEtag(c.req.header('if-none-match'), asset.etag)
|
|
1442
|
-
? assetNotModified(asset, options)
|
|
1443
|
-
: assetResponse(asset, options);
|
|
1444
|
-
}
|
|
1445
|
-
/** A request path as a path on disk: percent-encoding off, segment by segment. */
|
|
1446
|
-
function decodeVariantPath(relative) {
|
|
1447
|
-
try {
|
|
1448
|
-
return relative.split('/').map(decodeURIComponent).join('/');
|
|
1449
|
-
}
|
|
1450
|
-
catch {
|
|
1451
|
-
return relative;
|
|
1452
|
-
}
|
|
1453
|
-
}
|
|
1454
|
-
/**
|
|
1455
|
-
* A file from `content/uploads/`, at the URL Eleventy's passthrough copy puts
|
|
1456
|
-
* it at.
|
|
1457
|
-
*
|
|
1458
|
-
* Uploads are not documents — the index never sees them — so they are served
|
|
1459
|
-
* as files, with the same validators and the same traversal check the theme's
|
|
1460
|
-
* assets get. The cache lifetime is longer than a theme asset's because an
|
|
1461
|
-
* upload's URL names one set of bytes: the upload endpoint never overwrites,
|
|
1462
|
-
* it suffixes.
|
|
1463
|
-
*/
|
|
1464
|
-
function upload(c) {
|
|
1465
|
-
const relative = requestPath(c).slice(UPLOAD_ASSET_PREFIX.length);
|
|
1466
|
-
const asset = findUpload(relative, c.var.config.contentDir);
|
|
1467
|
-
if (asset === undefined)
|
|
1468
|
-
return notFound(c);
|
|
1469
|
-
const options = { maxAge: UPLOAD_ASSET_MAX_AGE };
|
|
1470
|
-
if (matchesEtag(c.req.header('if-none-match'), asset.etag)) {
|
|
1471
|
-
return assetNotModified(asset, options);
|
|
1472
|
-
}
|
|
1473
|
-
const part = assetRangeResponse(asset, c.req.header('range'), c.req.header('if-range'), options);
|
|
1474
|
-
const whole = part ?? assetResponse(asset, options);
|
|
1475
|
-
whole.headers.set('accept-ranges', 'bytes');
|
|
1476
|
-
return whole;
|
|
1477
|
-
}
|
|
1478
|
-
/** The URL of a page of the home listing, by zero-based index. */
|
|
1479
|
-
export function homeHref(index) {
|
|
1480
|
-
return listingPageHref('/', index);
|
|
1481
|
-
}
|
|
1482
|
-
/**
|
|
1483
|
-
* The URL of a page of the listing that hangs off `root`, by zero-based index.
|
|
1484
|
-
*
|
|
1485
|
-
* The first page is the root itself: `/` or the posts page's own permalink,
|
|
1486
|
-
* which is what makes a posts page one URL rather than two.
|
|
1487
|
-
*/
|
|
1488
|
-
export function listingPageHref(root, index) {
|
|
1489
|
-
return index === 0 ? root : `${root}${PAGE_SEGMENT}/${String(index + 1)}/`;
|
|
1490
|
-
}
|
|
1491
|
-
/**
|
|
1492
|
-
* What the theme is told about a taxonomy archive: the term under the name of
|
|
1493
|
-
* its taxonomy, and the layout that taxonomy uses.
|
|
1494
|
-
*/
|
|
1495
|
-
function taxonomyContext(term) {
|
|
1496
|
-
return term.taxonomy === 'tag'
|
|
1497
|
-
? { tag: term.term, template: TEMPLATES.tag }
|
|
1498
|
-
: { category: term.term, template: TEMPLATES.category };
|
|
1499
|
-
}
|
|
1500
|
-
/**
|
|
1501
|
-
* What the theme is told about an author archive: the person's profile under
|
|
1502
|
-
* `author`, the same shape a post's byline gets, and the layout an archive of
|
|
1503
|
-
* theirs uses.
|
|
1504
|
-
*
|
|
1505
|
-
* One shape for both places is the point. A theme that knows how to print a
|
|
1506
|
-
* byline already knows how to print the heading of the archive that byline
|
|
1507
|
-
* links to, and neither has to ask whether the site has users.
|
|
1508
|
-
*/
|
|
1509
|
-
function authorArchiveContext(author) {
|
|
1510
|
-
return { author: profileContext(author.user), template: TEMPLATES.author };
|
|
1511
|
-
}
|
|
1512
|
-
/**
|
|
1513
|
-
* The URL of a feed: the whole site's, or one taxonomy archive's.
|
|
1514
|
-
*
|
|
1515
|
-
* WordPress's layout, so a subscriber of a migrated site keeps polling the URL
|
|
1516
|
-
* they already hold: `/feed/` is RSS 2.0, `/feed/atom/` and `/feed/json/` are
|
|
1517
|
-
* its siblings, and an archive's feeds hang off the archive.
|
|
1518
|
-
*/
|
|
1519
|
-
export function feedHref(term, format, bases) {
|
|
1520
|
-
return feedPathUnder(listingHref({ term }, 0, bases), format);
|
|
1521
|
-
}
|
|
1522
|
-
/**
|
|
1523
|
-
* Where the site's comments feed lives, and where one document's does.
|
|
1524
|
-
*
|
|
1525
|
-
* WordPress's URLs, so a site migrated from it keeps both: the whole site's
|
|
1526
|
-
* comments at `/comments/feed/`, and a document's under its own permalink. There
|
|
1527
|
-
* is one format, RSS 2.0, because that is what a comments feed is read in.
|
|
1528
|
-
*/
|
|
1529
|
-
export function commentsFeedHref(document) {
|
|
1530
|
-
return commentsFeedPath(document === undefined ? undefined : encodePath(document.permalink));
|
|
1531
|
-
}
|
|
1532
|
-
function gone(c) {
|
|
1533
|
-
return c.html(c.var.renderer.renderGone(requestPath(c)), 410);
|
|
1534
|
-
}
|
|
1535
|
-
/** The theme's 404 page. */
|
|
1536
|
-
export function notFound(c) {
|
|
1537
|
-
return c.html(c.var.renderer.renderNotFound(requestPath(c)), 404);
|
|
1538
|
-
}
|
|
1539
|
-
/**
|
|
1540
|
-
* The requested path, percent-decoded, because permalinks are stored decoded.
|
|
1541
|
-
* A path whose escapes are malformed is used as it arrived, which resolves to
|
|
1542
|
-
* nothing and so 404s.
|
|
1543
|
-
*/
|
|
1544
|
-
export function requestPath(c) {
|
|
1545
|
-
const { pathname } = new URL(c.req.url);
|
|
1546
|
-
try {
|
|
1547
|
-
return decodeURIComponent(pathname);
|
|
1548
|
-
}
|
|
1549
|
-
catch {
|
|
1550
|
-
return pathname;
|
|
1551
|
-
}
|
|
1552
|
-
}
|
|
1553
|
-
/** A decoded path back into one safe to put in a `Location` header. */
|
|
1554
|
-
function encodePath(pathname) {
|
|
1555
|
-
return pathname
|
|
1556
|
-
.split('/')
|
|
1557
|
-
.map((segment) => encodeURIComponent(segment))
|
|
1558
|
-
.join('/');
|
|
285
|
+
? termHref(moved, asked.pageNumber, view.bases)
|
|
286
|
+
: feedHref(moved, feedPath.format, view.bases);
|
|
1559
287
|
}
|
|
1560
288
|
//# sourceMappingURL=routes.js.map
|