@geekity/cms 0.29.0 → 0.31.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 -4214
- package/admin/pages/settings/privacy.njk +1 -1
- 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 +5 -5
- package/dist/admin/app-activity.js.map +1 -0
- package/dist/admin/appearance.d.ts +3 -3
- package/dist/admin/appearance.d.ts.map +1 -1
- package/dist/admin/appearance.js +12 -6
- 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 +16 -17
- package/dist/admin/comments.js.map +1 -1
- 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 +18 -19
- 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/documents.d.ts +16 -301
- package/dist/admin/documents.d.ts.map +1 -1
- package/dist/admin/documents.js +74 -1032
- 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 -8
- 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 +1 -1
- package/dist/admin/editor-layout.js.map +1 -1
- package/dist/admin/federation.d.ts +5 -5
- package/dist/admin/federation.d.ts.map +1 -1
- package/dist/admin/federation.js +16 -18
- 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 +38 -20
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +27 -13
- 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} +17 -18
- package/dist/admin/indieauth-consent.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 +235 -0
- package/dist/admin/legacy-migrations.js.map +1 -0
- package/dist/admin/media.d.ts +4 -108
- package/dist/admin/media.d.ts.map +1 -1
- package/dist/admin/media.js +19 -187
- package/dist/admin/media.js.map +1 -1
- package/dist/admin/menu.d.ts.map +1 -1
- package/dist/admin/menu.js +7 -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 +10 -12
- 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 +9 -12
- 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 +11 -15
- 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 +28 -32
- 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 +10 -12
- 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 +28 -26
- package/dist/admin/routes.js.map +1 -1
- package/dist/admin/settings-discussion.d.ts.map +1 -1
- package/dist/admin/settings-discussion.js +7 -4
- package/dist/admin/settings-discussion.js.map +1 -1
- package/dist/admin/settings-email.d.ts +1 -1
- package/dist/admin/settings-email.d.ts.map +1 -1
- package/dist/admin/settings-email.js +13 -10
- package/dist/admin/settings-email.js.map +1 -1
- package/dist/admin/settings-general.d.ts.map +1 -1
- package/dist/admin/settings-general.js +10 -7
- package/dist/admin/settings-general.js.map +1 -1
- package/dist/admin/settings-page.d.ts +3 -4
- package/dist/admin/settings-page.d.ts.map +1 -1
- package/dist/admin/settings-page.js +5 -6
- 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 +1 -1
- package/dist/admin/settings-permalinks.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 +4 -3
- package/dist/admin/settings-reading.js.map +1 -1
- 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/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 +8 -11
- package/dist/admin/taxonomy.js.map +1 -1
- package/dist/admin/templates.js +1 -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 +83 -80
- package/dist/admin/users.js.map +1 -1
- package/dist/avatars/avatars.d.ts +2 -2
- package/dist/avatars/avatars.d.ts.map +1 -1
- package/dist/avatars/avatars.js +6 -9
- package/dist/avatars/avatars.js.map +1 -1
- package/dist/avatars/index.d.ts +0 -1
- package/dist/avatars/index.d.ts.map +1 -1
- package/dist/avatars/index.js +0 -1
- package/dist/avatars/index.js.map +1 -1
- package/dist/cache.d.ts +4 -2
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js +11 -5
- 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 +245 -267
- 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 +115 -0
- package/dist/cms/app.js.map +1 -0
- package/dist/cms/boot.d.ts +14 -0
- package/dist/cms/boot.d.ts.map +1 -0
- package/dist/cms/boot.js +107 -0
- package/dist/cms/boot.js.map +1 -0
- package/dist/cms/create.d.ts +248 -0
- package/dist/cms/create.d.ts.map +1 -0
- package/dist/cms/create.js +167 -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 +55 -0
- package/dist/cms/services.d.ts.map +1 -0
- package/dist/cms/services.js +353 -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 +15 -0
- package/dist/cms/site-records.js.map +1 -0
- package/dist/comments/akismet.d.ts +1 -1
- package/dist/comments/akismet.d.ts.map +1 -1
- package/dist/comments/akismet.js +1 -3
- package/dist/comments/akismet.js.map +1 -1
- package/dist/comments/conversation.d.ts +334 -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 +12 -6
- package/dist/comments/index.d.ts.map +1 -1
- package/dist/comments/index.js +7 -4
- 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 +1 -9
- package/dist/comments/policy.d.ts.map +1 -1
- package/dist/comments/policy.js +3 -18
- package/dist/comments/policy.js.map +1 -1
- package/dist/comments/records.d.ts +25 -173
- package/dist/comments/records.d.ts.map +1 -1
- package/dist/comments/records.js +69 -265
- package/dist/comments/records.js.map +1 -1
- package/dist/comments/reply-notices.d.ts +5 -5
- package/dist/comments/reply-notices.d.ts.map +1 -1
- package/dist/comments/reply-notices.js +6 -6
- 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 +7 -5
- 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 +22 -34
- package/dist/comments/routes.js.map +1 -1
- package/dist/comments/submission.d.ts +5 -100
- package/dist/comments/submission.d.ts.map +1 -1
- package/dist/comments/submission.js +5 -20
- 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 +116 -0
- package/dist/config-loader.js.map +1 -0
- package/dist/config.d.ts +72 -50
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +132 -180
- package/dist/config.js.map +1 -1
- package/dist/contact/delivery.d.ts +1 -1
- package/dist/contact/delivery.d.ts.map +1 -1
- package/dist/contact/delivery.js +5 -13
- 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 +2 -2
- package/dist/contact/index.d.ts.map +1 -1
- package/dist/contact/index.js +2 -2
- package/dist/contact/index.js.map +1 -1
- package/dist/contact/records.d.ts.map +1 -1
- package/dist/contact/records.js +8 -11
- 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 +3 -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 +195 -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} +39 -76
- 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 +25 -0
- package/dist/content/excerpt.d.ts.map +1 -0
- package/dist/content/excerpt.js +43 -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 +14 -19
- package/dist/content/guids.d.ts.map +1 -0
- package/dist/{web → content}/guids.js +30 -19
- 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 +9 -4
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/index.js +5 -2
- package/dist/content/index.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/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/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/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 +28 -0
- package/dist/content/photo-form.d.ts.map +1 -0
- package/dist/{admin/photo-field.js → content/photo-form.js} +36 -36
- package/dist/content/photo-form.js.map +1 -0
- package/dist/content/photo.d.ts +1 -1
- package/dist/content/photo.d.ts.map +1 -1
- package/dist/content/photo.js +1 -1
- 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 +256 -0
- package/dist/content/post-fields.js.map +1 -0
- package/dist/{admin/read-field.d.ts → content/read-form.d.ts} +6 -4
- package/dist/content/read-form.d.ts.map +1 -0
- package/dist/content/read-form.js +99 -0
- package/dist/content/read-form.js.map +1 -0
- package/dist/content/read.d.ts.map +1 -1
- package/dist/content/read.js +7 -11
- 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 -137
- package/dist/content/store.d.ts.map +1 -1
- package/dist/content/store.js +0 -1050
- 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 +27 -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 +566 -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 +5 -3
- package/dist/dev-mode.d.ts.map +1 -1
- package/dist/dev-mode.js +3 -3
- 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/exports.d.ts +26 -0
- package/dist/exports.d.ts.map +1 -0
- package/dist/exports.js +8 -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 +19 -32
- package/dist/federation/article.js.map +1 -1
- package/dist/federation/backfill.d.ts +4 -4
- 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.map +1 -1
- package/dist/federation/cited-post.js +2 -4
- 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 +7 -32
- package/dist/federation/delivery.d.ts.map +1 -1
- package/dist/federation/delivery.js +64 -201
- package/dist/federation/delivery.js.map +1 -1
- package/dist/federation/federation.d.ts +5 -5
- package/dist/federation/federation.d.ts.map +1 -1
- package/dist/federation/federation.js +7 -6
- 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/inbox.d.ts +1 -1
- package/dist/federation/inbox.d.ts.map +1 -1
- package/dist/federation/inbox.js +5 -4
- 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 +4 -47
- 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 +1 -1
- package/dist/federation/profiles.d.ts.map +1 -1
- package/dist/federation/profiles.js +5 -8
- package/dist/federation/profiles.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 +2 -3
- package/dist/federation/relays.d.ts.map +1 -1
- package/dist/federation/relays.js +22 -30
- package/dist/federation/relays.js.map +1 -1
- 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.map +1 -1
- package/dist/files/atomic.js +4 -9
- package/dist/files/atomic.js.map +1 -1
- 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 +88 -0
- package/dist/files/static-files.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 -1
- package/dist/forms/protection.d.ts.map +1 -1
- package/dist/forms/protection.js +3 -1
- package/dist/forms/protection.js.map +1 -1
- package/dist/images/icons.js +2 -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 +0 -20
- package/dist/images/markup.d.ts.map +1 -1
- package/dist/images/markup.js +5 -64
- package/dist/images/markup.js.map +1 -1
- package/dist/images/paths.d.ts +0 -10
- package/dist/images/paths.d.ts.map +1 -1
- package/dist/images/paths.js +3 -11
- package/dist/images/paths.js.map +1 -1
- package/dist/images/variants.d.ts +2 -2
- package/dist/images/variants.d.ts.map +1 -1
- package/dist/images/variants.js +4 -3
- package/dist/images/variants.js.map +1 -1
- package/dist/index.d.ts +3 -291
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -838
- package/dist/index.js.map +1 -1
- package/dist/indexnow.d.ts.map +1 -1
- package/dist/indexnow.js +21 -26
- 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 -1
- package/dist/indieauth/tokens.d.ts.map +1 -1
- package/dist/indieauth/tokens.js +2 -2
- package/dist/indieauth/tokens.js.map +1 -1
- package/dist/mail/index.d.ts +1 -5
- package/dist/mail/index.d.ts.map +1 -1
- package/dist/mail/index.js +0 -2
- 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 +1 -1
- package/dist/maintenance.d.ts.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 +157 -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 +29 -40
- package/dist/micropub/endpoint.js.map +1 -1
- package/dist/micropub/media.d.ts +1 -1
- package/dist/micropub/media.d.ts.map +1 -1
- package/dist/micropub/media.js +6 -6
- 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 +4 -4
- package/dist/notifications/comments.d.ts.map +1 -1
- package/dist/notifications/comments.js +6 -14
- package/dist/notifications/comments.js.map +1 -1
- package/dist/notifications/digest.d.ts +4 -4
- package/dist/notifications/digest.d.ts.map +1 -1
- package/dist/notifications/digest.js +6 -16
- package/dist/notifications/digest.js.map +1 -1
- package/dist/notifications/index.d.ts +6 -3
- package/dist/notifications/index.d.ts.map +1 -1
- package/dist/notifications/index.js +3 -2
- 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} +7 -13
- package/dist/notifications/mail-service.d.ts.map +1 -0
- package/dist/{mail/service.js → notifications/mail-service.js} +33 -54
- 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/tokens.d.ts +2 -2
- package/dist/notifications/tokens.d.ts.map +1 -1
- package/dist/notifications/tokens.js +2 -2
- package/dist/notifications/tokens.js.map +1 -1
- package/dist/notify.d.ts.map +1 -1
- package/dist/notify.js +12 -24
- package/dist/notify.js.map +1 -1
- package/dist/plugin.d.ts +48 -2
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +28 -2
- package/dist/plugin.js.map +1 -1
- package/dist/plugins/enabled.d.ts.map +1 -1
- package/dist/plugins/enabled.js +2 -4
- 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.map +1 -1
- package/dist/plugins/install.js +7 -3
- 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/registry.d.ts.map +1 -1
- package/dist/plugins/registry.js +7 -9
- package/dist/plugins/registry.js.map +1 -1
- package/dist/plugins/settings.d.ts.map +1 -1
- package/dist/plugins/settings.js +2 -3
- package/dist/plugins/settings.js.map +1 -1
- package/dist/plugins/site.d.ts +1 -1
- package/dist/plugins/site.d.ts.map +1 -1
- package/dist/plugins/site.js +10 -4
- 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 +2 -2
- package/dist/privacy/retention.d.ts.map +1 -1
- package/dist/privacy/retention.js +9 -11
- package/dist/privacy/retention.js.map +1 -1
- 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/{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 +46 -0
- package/dist/site/setting-rows.d.ts.map +1 -0
- package/dist/site/setting-rows.js +480 -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 +58 -0
- package/dist/site/settings-form.js.map +1 -0
- package/dist/site/settings.d.ts +345 -0
- package/dist/site/settings.d.ts.map +1 -0
- package/dist/site/settings.js +107 -0
- package/dist/site/settings.js.map +1 -0
- package/dist/site/site-json.d.ts +69 -0
- package/dist/site/site-json.d.ts.map +1 -0
- package/dist/site/site-json.js +113 -0
- package/dist/site/site-json.js.map +1 -0
- package/dist/{admin/accounts.d.ts → site/users.d.ts} +25 -41
- package/dist/site/users.d.ts.map +1 -0
- package/dist/{admin/accounts.js → site/users.js} +49 -155
- 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/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/primary.d.ts +1 -1
- package/dist/supervisor/primary.d.ts.map +1 -1
- package/dist/supervisor/primary.js +31 -11
- 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 +48 -0
- package/dist/web/asset-routes.d.ts.map +1 -0
- package/dist/web/asset-routes.js +107 -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} +14 -17
- package/dist/web/contact-routes.js.map +1 -0
- package/dist/web/context.d.ts +1 -187
- package/dist/web/context.d.ts.map +1 -1
- package/dist/web/context.js +5 -171
- package/dist/web/context.js.map +1 -1
- package/dist/web/conversation.d.ts +6 -333
- package/dist/web/conversation.d.ts.map +1 -1
- package/dist/web/conversation.js +280 -220
- 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 +136 -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 +28 -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} +27 -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 +280 -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 +8 -72
- 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 +36 -0
- package/dist/web/feed-routes.d.ts.map +1 -0
- package/dist/web/feed-routes.js +124 -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 +13 -40
- package/dist/web/feed-source.d.ts.map +1 -1
- package/dist/web/feed-source.js +14 -43
- 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/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 -3
- package/dist/web/indieauth-activity-log.d.ts.map +1 -0
- package/dist/{indieauth/activity-log.js → web/indieauth-activity-log.js} +5 -6
- 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} +4 -4
- package/dist/web/indieauth-bearer.js.map +1 -0
- package/dist/{indieauth/discovery.d.ts → web/indieauth-discovery.d.ts} +2 -7
- package/dist/web/indieauth-discovery.d.ts.map +1 -0
- package/dist/{indieauth/discovery.js → web/indieauth-discovery.js} +6 -9
- 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} +7 -7
- 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 +148 -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 +7 -13
- 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 +15 -0
- package/dist/web/page-sources.d.ts.map +1 -0
- package/dist/web/page-sources.js +44 -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} +5 -5
- 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 +43 -7
- package/dist/web/render.d.ts.map +1 -1
- package/dist/web/render.js +96 -48
- 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 +112 -1373
- 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 +143 -0
- package/dist/web/site-index.js.map +1 -0
- package/dist/web/site-view.d.ts +45 -0
- package/dist/web/site-view.d.ts.map +1 -0
- package/dist/web/site-view.js +67 -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 +5 -14
- 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 +4 -6
- 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 +12 -4
- package/dist/webmention/pingback.d.ts.map +1 -1
- package/dist/webmention/pingback.js +4 -102
- package/dist/webmention/pingback.js.map +1 -1
- package/dist/webmention/receive.d.ts +7 -4
- package/dist/webmention/receive.d.ts.map +1 -1
- package/dist/webmention/receive.js +34 -42
- 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 +3 -3
- package/dist/webmention/reply-contexts.d.ts.map +1 -1
- package/dist/webmention/reply-contexts.js +7 -10
- 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 +7 -7
- package/dist/webmention/service.d.ts.map +1 -1
- package/dist/webmention/service.js +49 -61
- 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 +5 -1
- package/themes/default/README.md +36 -2329
- package/themes/default/layouts/base.njk +5 -4
- package/themes/default/layouts/comment.njk +3 -3
- 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/comment.njk +5 -5
- 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/src/style.css +6 -6
- 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.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 -998
- package/dist/admin/store.d.ts.map +0 -1
- package/dist/admin/store.js +0 -1588
- 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/admin/documents.js
CHANGED
|
@@ -1,70 +1,54 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { PINNED_FRONT_MATTER_KEY, PINNED_POST_LIMIT, pinnedAt } from '../content/pinned.js';
|
|
9
|
-
import { discoverPostType, postLabel, replyTarget } from '../content/post-type.js';
|
|
10
|
-
import { isReadStatus, READ_OF_FRONT_MATTER_KEY, READ_STATUS_FRONT_MATTER_KEY, READ_STATUS_LABELS, READ_STATUSES, readWork, readWorkFrontMatter, } from '../content/read.js';
|
|
11
|
-
import { respellTags } from '../content/tags.js';
|
|
12
|
-
import { RSVP_FRONT_MATTER_KEY, RSVP_LABELS, RSVP_VALUES, rsvpValue } from '../content/rsvp.js';
|
|
13
|
-
import { ENCLOSURE_FRONT_MATTER_KEY, enclosureOf, isWebUrl, TRANSCRIPT_TYPES, } from '../content/enclosure.js';
|
|
14
|
-
import { PHOTO_FRONT_MATTER_KEY, photoFrontMatter } from '../content/photo.js';
|
|
15
|
-
import { keptProperties } from '../content/kept-properties.js';
|
|
1
|
+
import { CITATION_PROPERTIES, citedHost, citesAnImage, shownInFull } from '../content/citation.js';
|
|
2
|
+
import { AUTHOR_UNTIL_REQUEST, blankForm, CITATION_FIELDS, COMMENT_SETTINGS, extraFromForm, formFor, formInReplyTo, postFieldsForm, splitTags, } from '../content/document-form.js';
|
|
3
|
+
import { PAGE_KIND, POST_KIND } from '../content/document-kind.js';
|
|
4
|
+
import { TRANSCRIPT_TYPES } from '../content/enclosure.js';
|
|
5
|
+
import { ENCLOSURE_FIELDS } from '../content/enclosure-form.js';
|
|
6
|
+
import { EVENT_FIELDS } from '../content/event-form.js';
|
|
7
|
+
import { BLANK_LOCATION_FORM } from '../content/location-form.js';
|
|
16
8
|
import { postLocations } from '../content/locations.js';
|
|
17
|
-
import {
|
|
9
|
+
import { PHOTO_FIELDS } from '../content/photo-form.js';
|
|
10
|
+
import { syndicateToField } from '../content/post-fields.js';
|
|
11
|
+
import { postLabel } from '../content/post-type.js';
|
|
12
|
+
import { isReadStatus, READ_STATUS_LABELS, READ_STATUSES } from '../content/read.js';
|
|
13
|
+
import { READ_FIELDS } from '../content/read-form.js';
|
|
14
|
+
import { RSVP_LABELS, RSVP_VALUES, rsvpValue } from '../content/rsvp.js';
|
|
18
15
|
import { scheduledFor } from '../content/schedule.js';
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
16
|
+
import { isTrashedPath } from '../content/store.js';
|
|
17
|
+
import { zoneLabel } from '../content/time.js';
|
|
18
|
+
import { moveDocumentFile } from '../content/trash.js';
|
|
19
|
+
import { isVisibility, visibilityOf } from '../content/visibility.js';
|
|
20
|
+
import { missingAltText, writeDocument } from '../content/write.js';
|
|
21
|
+
import { currentUsername, documentSite } from '../web/document-site.js';
|
|
24
22
|
import { normalizeBody, serializeDocument } from '../content/writer.js';
|
|
25
|
-
import { readAltTexts
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
import { authorNames, userForAuthor } from '../web/authors.js';
|
|
33
|
-
import { findUserById, listUsers } from './accounts.js';
|
|
23
|
+
import { readAltTexts } from '../content/alt-text.js';
|
|
24
|
+
import { readSiteSettings } from '../site/site-json.js';
|
|
25
|
+
import { listUsers } from '../site/users.js';
|
|
26
|
+
import { stringOrEmpty } from '../util/forms.js';
|
|
27
|
+
import { userForAuthor } from '../content/authors.js';
|
|
28
|
+
import { isServed } from '../content/served.js';
|
|
29
|
+
import { syndicationTargetsReader } from '../webmention/syndication.js';
|
|
34
30
|
import { editorActionViews } from './editor-actions.js';
|
|
31
|
+
import { BLANK_ALTERNATE_ROW, enclosureChoices, LOCATION_FIELDS, photoChoices, photoRowViews, readLocationForm, } from './editor-fields.js';
|
|
32
|
+
import { openGroups } from './editor-layout.js';
|
|
35
33
|
import { flash } from './flash.js';
|
|
36
34
|
import { formatInTimezone } from './formatting.js';
|
|
37
|
-
import {
|
|
35
|
+
import { allowGeolocation } from './headers.js';
|
|
38
36
|
import { PREVIEW_PATH } from './preview.js';
|
|
39
|
-
import { ADMIN_PREFIX } from '
|
|
37
|
+
import { ADMIN_PREFIX } from '../site/admin-paths.js';
|
|
40
38
|
import { ADMIN_TEMPLATES } from './templates.js';
|
|
41
39
|
import { UPLOADS_PATH } from './uploads.js';
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
*
|
|
55
|
-
* The CMS does not model it — it is not in `KNOWN_FRONT_MATTER_KEYS` — so the
|
|
56
|
-
* parser leaves it in {@link Document.extra} and the editor reads and writes it
|
|
57
|
-
* there, alongside every other key somebody added by hand.
|
|
58
|
-
*/
|
|
59
|
-
export const EXCLUDE_KEY = 'eleventyExcludeFromCollections';
|
|
60
|
-
/**
|
|
61
|
-
* What the editor's Comments field can say: leave it to the site's rules, hold
|
|
62
|
-
* this document open, or close it.
|
|
63
|
-
*
|
|
64
|
-
* The values are the strings the form submits and the template renders as
|
|
65
|
-
* options, spelled once so the two cannot drift.
|
|
66
|
-
*/
|
|
67
|
-
export const COMMENT_SETTINGS = { site: '', open: 'open', closed: 'closed' };
|
|
40
|
+
export const POST_SCREENS = {
|
|
41
|
+
...POST_KIND,
|
|
42
|
+
section: 'posts',
|
|
43
|
+
basePath: `${ADMIN_PREFIX}/posts`,
|
|
44
|
+
plural: 'Posts',
|
|
45
|
+
};
|
|
46
|
+
export const PAGE_SCREENS = {
|
|
47
|
+
...PAGE_KIND,
|
|
48
|
+
section: 'pages',
|
|
49
|
+
basePath: `${ADMIN_PREFIX}/pages`,
|
|
50
|
+
plural: 'Pages',
|
|
51
|
+
};
|
|
68
52
|
/** A submitted Comments field, or the site default for anything else. */
|
|
69
53
|
function commentSetting(value) {
|
|
70
54
|
return value === COMMENT_SETTINGS.open || value === COMMENT_SETTINGS.closed
|
|
@@ -76,41 +60,6 @@ function formVisibility(value) {
|
|
|
76
60
|
return 'public';
|
|
77
61
|
return isVisibility(value) ? value : { unrecognized: value };
|
|
78
62
|
}
|
|
79
|
-
/** What a document's front matter already says about comments. */
|
|
80
|
-
function commentSettingOf(document) {
|
|
81
|
-
const own = document.extra[COMMENTS_FRONT_MATTER_KEY];
|
|
82
|
-
if (own === true)
|
|
83
|
-
return COMMENT_SETTINGS.open;
|
|
84
|
-
if (own === false)
|
|
85
|
-
return COMMENT_SETTINGS.closed;
|
|
86
|
-
return COMMENT_SETTINGS.site;
|
|
87
|
-
}
|
|
88
|
-
/** The posts screens: dated, tagged, categorised, filed under `posts/`. */
|
|
89
|
-
export const POST_KIND = {
|
|
90
|
-
type: 'post',
|
|
91
|
-
section: 'posts',
|
|
92
|
-
basePath: `${ADMIN_PREFIX}/posts`,
|
|
93
|
-
singular: 'post',
|
|
94
|
-
plural: 'Posts',
|
|
95
|
-
dated: true,
|
|
96
|
-
tagged: true,
|
|
97
|
-
categorised: true,
|
|
98
|
-
excludable: false,
|
|
99
|
-
contactable: false,
|
|
100
|
-
};
|
|
101
|
-
/** The pages screens: standing content, no date prefix and no taxonomy. */
|
|
102
|
-
export const PAGE_KIND = {
|
|
103
|
-
type: 'page',
|
|
104
|
-
section: 'pages',
|
|
105
|
-
basePath: `${ADMIN_PREFIX}/pages`,
|
|
106
|
-
singular: 'page',
|
|
107
|
-
plural: 'Pages',
|
|
108
|
-
dated: false,
|
|
109
|
-
tagged: false,
|
|
110
|
-
categorised: false,
|
|
111
|
-
excludable: true,
|
|
112
|
-
contactable: true,
|
|
113
|
-
};
|
|
114
63
|
/** The URL of the editor for one document. */
|
|
115
64
|
export function editorPath(kind, slug) {
|
|
116
65
|
return `${kind.basePath}/${encodeURIComponent(slug)}`;
|
|
@@ -145,7 +94,7 @@ export const DOCUMENTS_PER_PAGE = 25;
|
|
|
145
94
|
export function documentFilter(value) {
|
|
146
95
|
return DOCUMENT_FILTERS.includes(value) ? value : 'all';
|
|
147
96
|
}
|
|
148
|
-
/** {@link
|
|
97
|
+
/** {@link CatalogReader.listAll} options for one kind and one filter. */
|
|
149
98
|
export function listOptionsFor(kind, filter) {
|
|
150
99
|
return {
|
|
151
100
|
type: kind.type,
|
|
@@ -159,7 +108,7 @@ export function listOptionsFor(kind, filter) {
|
|
|
159
108
|
* Register the listing and the editor for one kind of document.
|
|
160
109
|
*
|
|
161
110
|
* Both `/admin/posts` and `/admin/pages` are this function with a different
|
|
162
|
-
* {@link
|
|
111
|
+
* {@link DocumentScreens}: the screens, the templates and the write path are
|
|
163
112
|
* shared, and the kind decides what a file is called, whether the form has a
|
|
164
113
|
* date and a taxonomy, and which section of the navigation marks itself.
|
|
165
114
|
*/
|
|
@@ -213,7 +162,7 @@ export function mountDocumentScreens(app, options) {
|
|
|
213
162
|
kind,
|
|
214
163
|
render,
|
|
215
164
|
document,
|
|
216
|
-
form: formFor(document, siteTimezone(c), location),
|
|
165
|
+
form: formFor(kind, document, siteTimezone(c), location),
|
|
217
166
|
});
|
|
218
167
|
});
|
|
219
168
|
app.post(`${kind.basePath}/:slug`, async (c) => {
|
|
@@ -221,9 +170,9 @@ export function mountDocumentScreens(app, options) {
|
|
|
221
170
|
if (document === undefined)
|
|
222
171
|
return c.notFound();
|
|
223
172
|
const body = await c.req.parseBody();
|
|
224
|
-
const action =
|
|
173
|
+
const action = stringOrEmpty(body['action']);
|
|
225
174
|
if (action === 'trash' || action === 'restore') {
|
|
226
|
-
return moveDocument(c, { kind, document, action, returnTo:
|
|
175
|
+
return moveDocument(c, { kind, document, action, returnTo: stringOrEmpty(body['return']) });
|
|
227
176
|
}
|
|
228
177
|
return saveFromForm(c, { kind, render, document, body });
|
|
229
178
|
});
|
|
@@ -233,40 +182,27 @@ export function mountDocumentScreens(app, options) {
|
|
|
233
182
|
* and for an editor action.
|
|
234
183
|
*/
|
|
235
184
|
export function submittedForm(kind, body, contentDir) {
|
|
185
|
+
const declared = syndicationTargetsReader(contentDir)();
|
|
236
186
|
return {
|
|
237
|
-
title:
|
|
238
|
-
slug:
|
|
239
|
-
permalink:
|
|
240
|
-
date:
|
|
241
|
-
tags:
|
|
242
|
-
categories:
|
|
243
|
-
description:
|
|
244
|
-
author:
|
|
245
|
-
inReplyTo:
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
readStatus: kind.type === 'post' ? text(body[READ_FIELDS.status]).trim() : '',
|
|
249
|
-
readOf: kind.type === 'post' ? submittedReadOfForm(body) : BLANK_READ_OF_FORM,
|
|
250
|
-
event: kind.type === 'post' ? submittedEventForm(body) : BLANK_EVENT_FORM,
|
|
251
|
-
lang: text(body['lang']).trim(),
|
|
187
|
+
title: stringOrEmpty(body['title']).trim(),
|
|
188
|
+
slug: stringOrEmpty(body['slug']).trim(),
|
|
189
|
+
permalink: stringOrEmpty(body['permalink']).trim(),
|
|
190
|
+
date: stringOrEmpty(body['date']).trim(),
|
|
191
|
+
tags: stringOrEmpty(body['tags']).trim(),
|
|
192
|
+
categories: stringOrEmpty(body['categories']).trim(),
|
|
193
|
+
description: stringOrEmpty(body['description']).trim(),
|
|
194
|
+
author: stringOrEmpty(body['author']).trim(),
|
|
195
|
+
inReplyTo: stringOrEmpty(body['in-reply-to']).trim(),
|
|
196
|
+
...postFieldsForm(kind, (field) => field.submitted(body, declared)),
|
|
197
|
+
lang: stringOrEmpty(body['lang']).trim(),
|
|
252
198
|
draft: body['draft'] !== undefined,
|
|
253
|
-
visibility: formVisibility(
|
|
199
|
+
visibility: formVisibility(stringOrEmpty(body['visibility'])),
|
|
254
200
|
exclude: body['exclude'] !== undefined,
|
|
255
201
|
contact: body['contact'] !== undefined,
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
enclosure: kind.type === 'post' ? readEnclosureForm(body) : BLANK_ENCLOSURE_FORM,
|
|
261
|
-
photos: kind.type === 'post' ? readPhotoForm(body) : [],
|
|
262
|
-
location: kind.type === 'post' ? readLocationForm(body) : BLANK_LOCATION_FORM,
|
|
263
|
-
syndicateTo: kind.type === 'post'
|
|
264
|
-
? syndicationTargetsReader(contentDir)()
|
|
265
|
-
.filter((target) => body[syndicateToField(target)] !== undefined)
|
|
266
|
-
.map((target) => target.id)
|
|
267
|
-
: [],
|
|
268
|
-
body: normalizeBody(text(body['body'])),
|
|
269
|
-
hash: text(body['hash']),
|
|
202
|
+
comments: commentSetting(stringOrEmpty(body['comments'])),
|
|
203
|
+
location: kind.located ? readLocationForm(body) : BLANK_LOCATION_FORM,
|
|
204
|
+
body: normalizeBody(stringOrEmpty(body['body'])),
|
|
205
|
+
hash: stringOrEmpty(body['hash']),
|
|
270
206
|
};
|
|
271
207
|
}
|
|
272
208
|
/**
|
|
@@ -279,7 +215,7 @@ async function saveFromForm(c, options) {
|
|
|
279
215
|
const store = c.var.store;
|
|
280
216
|
const contentDir = c.var.config.contentDir;
|
|
281
217
|
const form = submittedForm(kind, body, contentDir);
|
|
282
|
-
const action =
|
|
218
|
+
const action = stringOrEmpty(body['action']);
|
|
283
219
|
// The buttons doc-5 names are shortcuts past the checkbox: Save draft and
|
|
284
220
|
// Publish say what they do, and Update leaves the decision to the checkbox.
|
|
285
221
|
const draft = action === 'save-draft' ? true : action === 'publish' ? false : form.draft;
|
|
@@ -314,322 +250,6 @@ async function saveFromForm(c, options) {
|
|
|
314
250
|
flash(c, 'warning', missingAltText(undescribed));
|
|
315
251
|
return c.redirect(documentEditorPath(kind, saved), 303);
|
|
316
252
|
}
|
|
317
|
-
/**
|
|
318
|
-
* The write path as one request reaches it, writing as `writer`: by default
|
|
319
|
-
* whoever the admin session names.
|
|
320
|
-
*/
|
|
321
|
-
export function documentSite(c, writer = currentUsername(c)) {
|
|
322
|
-
return {
|
|
323
|
-
store: c.var.store,
|
|
324
|
-
config: c.var.config,
|
|
325
|
-
announce: c.var.announce,
|
|
326
|
-
writer,
|
|
327
|
-
citedContext: (target) => c.var.replyContexts.describe(target),
|
|
328
|
-
storedContext: (target) => c.var.replyContexts.read(target),
|
|
329
|
-
learnHandles: c.var.learnHandles,
|
|
330
|
-
};
|
|
331
|
-
}
|
|
332
|
-
/**
|
|
333
|
-
* The write path behind the editor and Micropub (TASK-164): one form in, one
|
|
334
|
-
* file out, announced to every subscriber.
|
|
335
|
-
*
|
|
336
|
-
* The order matters: the form is checked before anything is touched, the
|
|
337
|
-
* on-disk file is re-hashed and compared with the hash the form loaded with
|
|
338
|
-
* (doc-1's conflict rule), and only then is a file written. A write that is
|
|
339
|
-
* refused leaves the content directory exactly as it was.
|
|
340
|
-
*/
|
|
341
|
-
export async function writeDocument(site, write) {
|
|
342
|
-
const { store, config, writer } = site;
|
|
343
|
-
const { kind, document, form, draft } = write;
|
|
344
|
-
const contentDir = config.contentDir;
|
|
345
|
-
function refused(message, field) {
|
|
346
|
-
return { outcome: 'refused', message, field };
|
|
347
|
-
}
|
|
348
|
-
// A post with no title is a note; a page is always named.
|
|
349
|
-
if (form.title === '' && kind.type === 'page') {
|
|
350
|
-
return refused(`A ${kind.singular} needs a title.`, 'editor-title');
|
|
351
|
-
}
|
|
352
|
-
// A post is a reply only when the target is a URL (Post Type Discovery), so
|
|
353
|
-
// anything else would be saved as a reply that is not one.
|
|
354
|
-
if (kind.type === 'post' && form.inReplyTo !== '' && replyTarget(form) === undefined) {
|
|
355
|
-
return refused('In reply to has to be a web address, like https://example.com/a-post/.', 'editor-in-reply-to');
|
|
356
|
-
}
|
|
357
|
-
if (kind.type === 'post' && form.rsvp !== '') {
|
|
358
|
-
if (rsvpValue(form.rsvp) === undefined) {
|
|
359
|
-
return refused(`RSVP is ${RSVP_VALUES.join(', ')}, not ${form.rsvp}.`, 'editor-rsvp');
|
|
360
|
-
}
|
|
361
|
-
if (form.inReplyTo === '') {
|
|
362
|
-
return refused('An RSVP answers an event. Put the event’s address in In reply to.', 'editor-in-reply-to');
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
let read;
|
|
366
|
-
if (kind.type === 'post') {
|
|
367
|
-
for (const property of CITATION_PROPERTIES) {
|
|
368
|
-
const cited = form[CITATION_FIELDS[property]];
|
|
369
|
-
if (cited !== '' && !isWebUrl(cited)) {
|
|
370
|
-
return refused(`${CITATION_LABELS[property]} has to be a web address, like https://example.com/a-post/.`, `editor-${property}`);
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
const resolved = resolveRead(form.readStatus, form.readOf);
|
|
374
|
-
if ('error' in resolved)
|
|
375
|
-
return refused(resolved.error, resolved.field);
|
|
376
|
-
read = resolved.read;
|
|
377
|
-
}
|
|
378
|
-
if (read !== undefined && form.description !== '') {
|
|
379
|
-
return refused('A read is described by what it says, so it keeps no Description. Empty Description to save it.', 'editor-description');
|
|
380
|
-
}
|
|
381
|
-
if (form.lang !== '' && !LANGUAGE_TAG_PATTERN.test(form.lang)) {
|
|
382
|
-
return refused('That is not a language tag, such as en, fr or pt-BR.', 'editor-lang');
|
|
383
|
-
}
|
|
384
|
-
let media = { recording: undefined, photos: [] };
|
|
385
|
-
if (kind.type === 'post') {
|
|
386
|
-
const resolved = resolveEnclosure(form.enclosure, document === undefined ? undefined : enclosureOf(document.extra), contentDir);
|
|
387
|
-
if ('error' in resolved)
|
|
388
|
-
return refused(resolved.error, resolved.field);
|
|
389
|
-
const photos = resolvePhotos(form.photos, contentDir);
|
|
390
|
-
if ('error' in photos)
|
|
391
|
-
return refused(photos.error, photos.field);
|
|
392
|
-
media = { recording: resolved.enclosure, photos: photos.photos };
|
|
393
|
-
}
|
|
394
|
-
let location;
|
|
395
|
-
if (kind.type === 'post') {
|
|
396
|
-
const resolved = resolveLocation(form.location);
|
|
397
|
-
if ('error' in resolved)
|
|
398
|
-
return refused(resolved.error, resolved.field);
|
|
399
|
-
location = resolved.location;
|
|
400
|
-
}
|
|
401
|
-
// TASK-207: a pin is new when the file does not carry one yet, and only a
|
|
402
|
-
// new one can take an author past Mastodon's limit.
|
|
403
|
-
if (form.pinned && (document === undefined || pinnedAt(document) === undefined)) {
|
|
404
|
-
const users = listUsers(config.dataDir);
|
|
405
|
-
const author = userForAuthor(users, chosenAuthor(config.dataDir, form.author, document, writer) ?? '');
|
|
406
|
-
const names = author === undefined ? [] : authorNames(users, author);
|
|
407
|
-
if (store.listPinnedByAuthor(names).length >= PINNED_POST_LIMIT) {
|
|
408
|
-
return refused(`You can pin up to ${String(PINNED_POST_LIMIT)} posts. Unpin one first.`, 'editor-pinned');
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
// TASK-141: an image nobody described is a problem to fix before readers
|
|
412
|
-
// meet it. A draft is not checked, since nobody meets a draft.
|
|
413
|
-
// A photo counts too, unless the media library describes it (TASK-166).
|
|
414
|
-
const library = readAltTexts(contentDir);
|
|
415
|
-
const undescribed = draft
|
|
416
|
-
? []
|
|
417
|
-
: [
|
|
418
|
-
...undescribedPhotos(media.photos, library),
|
|
419
|
-
...undescribedImages(renderMarkdown(form.body), library),
|
|
420
|
-
];
|
|
421
|
-
if (undescribed.length > 0 && config.requireAltText) {
|
|
422
|
-
return refused(`This site publishes no image without alt text. ${missingAltText(undescribed)}`);
|
|
423
|
-
}
|
|
424
|
-
if (!draft &&
|
|
425
|
-
config.requireAltText &&
|
|
426
|
-
kind.type === 'post' &&
|
|
427
|
-
(await citesUndescribedImage(site, document, form))) {
|
|
428
|
-
return refused('This site publishes no image without alt text. Describe the image this post reposts in its alt text field.', 'editor-cited-alt');
|
|
429
|
-
}
|
|
430
|
-
const timezone = readSiteSettings(contentDir).timezone;
|
|
431
|
-
if (kind.type === 'post') {
|
|
432
|
-
const resolved = resolveEvent(form.event, timezone);
|
|
433
|
-
if ('error' in resolved)
|
|
434
|
-
return refused(resolved.error, resolved.field);
|
|
435
|
-
if (resolved.event !== undefined && form.title === '') {
|
|
436
|
-
return refused('An event needs a name. Put it in Title.', 'editor-title');
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
// decision-11: what the file gets is a UTC instant, and an offset-less field
|
|
440
|
-
// is the site's own wall clock rather than the server's.
|
|
441
|
-
const typed = kind.dated ? (form.date === '' ? store.now().toISOString() : form.date) : undefined;
|
|
442
|
-
if (typed !== undefined && !/^\d{4}-\d{2}-\d{2}/.test(typed)) {
|
|
443
|
-
return refused('A date has to start with a year, a month and a day, like 2026-03-04.', 'editor-date');
|
|
444
|
-
}
|
|
445
|
-
const date = typed === undefined ? undefined : toUtcInstant(typed, timezone);
|
|
446
|
-
if (typed !== undefined && date === undefined) {
|
|
447
|
-
return refused('That date is not one anybody can read. Try 2026-03-04 09:00.', 'editor-date');
|
|
448
|
-
}
|
|
449
|
-
const slug = slugify(form.slug) ||
|
|
450
|
-
slugify(form.title) ||
|
|
451
|
-
(document?.slug ?? '') ||
|
|
452
|
-
noteSlug(form.body) ||
|
|
453
|
-
slugify(form.readOf.name) ||
|
|
454
|
-
(await typeSlug(kind, form, media.photos, site.citedContext)) ||
|
|
455
|
-
'untitled';
|
|
456
|
-
const trashed = document !== undefined && isTrashedPath(document.path);
|
|
457
|
-
// The calendar day the document is filed under: the site zone's day at its
|
|
458
|
-
// date for a new one, and the day already in the filename for one whose date
|
|
459
|
-
// has not moved, so a zone changed later never moves a URL that exists.
|
|
460
|
-
const filed = filedDay({ date, document, timezone });
|
|
461
|
-
// A new document gets out of the way of anything that already holds its
|
|
462
|
-
// name; an existing one keeps the slug it was given.
|
|
463
|
-
const finalSlug = document === undefined
|
|
464
|
-
? await freeSlug({ contentDir, store, type: kind.type, slug, date: filed })
|
|
465
|
-
: slug;
|
|
466
|
-
// A URL somebody has been shown only moves when the author asks it to, by
|
|
467
|
-
// editing the slug or the permalink: correcting a date refiles the file and
|
|
468
|
-
// leaves the URL where it was. An empty permalink field is a form that
|
|
469
|
-
// carried none, not a request to move.
|
|
470
|
-
const promised = promisedDocument(document, store.now(), contentDir);
|
|
471
|
-
const submitted = normalizePermalink(form.permalink);
|
|
472
|
-
const asked = promised !== undefined &&
|
|
473
|
-
(finalSlug !== promised.slug || (submitted !== undefined && submitted !== promised.permalink));
|
|
474
|
-
const permalink = promised !== undefined && !asked
|
|
475
|
-
? promised.permalink
|
|
476
|
-
: resolvePermalink({
|
|
477
|
-
kind,
|
|
478
|
-
form,
|
|
479
|
-
slug: finalSlug,
|
|
480
|
-
date: filed,
|
|
481
|
-
document,
|
|
482
|
-
timezone,
|
|
483
|
-
});
|
|
484
|
-
const target = documentPath({ kind, slug: finalSlug, date: filed, trashed });
|
|
485
|
-
if (document !== undefined) {
|
|
486
|
-
const conflict = await conflictWith(contentDir, document, form.hash);
|
|
487
|
-
if (conflict !== undefined) {
|
|
488
|
-
return { outcome: 'conflict', document, media, conflict };
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
if (target !== document?.path && store.getByPath(target) !== undefined) {
|
|
492
|
-
return refused(`Another ${kind.singular} already lives in ${target}.`, 'editor-slug');
|
|
493
|
-
}
|
|
494
|
-
const tags = respellTags(kind.tagged ? splitTags(form.tags) : [], (tag) => store.tagSpelling(tag, { excluding: document?.path }));
|
|
495
|
-
const content = {
|
|
496
|
-
title: form.title,
|
|
497
|
-
...(date === undefined ? {} : { date }),
|
|
498
|
-
updated: store.now().toISOString(),
|
|
499
|
-
permalink,
|
|
500
|
-
...optional('redirectFrom', formerPermalinks(document, promised, permalink)),
|
|
501
|
-
tags: tags.tags,
|
|
502
|
-
categories: kind.categorised ? splitTags(form.categories) : [],
|
|
503
|
-
draft,
|
|
504
|
-
...(form.description === '' ? {} : { description: form.description }),
|
|
505
|
-
...optional('author', chosenAuthor(config.dataDir, form.author, document, writer)),
|
|
506
|
-
...optional('inReplyTo', replyTo(kind, form, document)),
|
|
507
|
-
...optional('activitypub', keptIdentity(document, promised, permalink, config.baseUrl)),
|
|
508
|
-
extra: keptGuid(resolveExtra(kind, document, form, store.now(), media, syndicationTargetsReader(contentDir)(), timezone), promised, permalink, config.baseUrl),
|
|
509
|
-
body: form.body,
|
|
510
|
-
};
|
|
511
|
-
// The row for the old path goes first: a rename briefly leaves two rows
|
|
512
|
-
// claiming one permalink, and the index refuses that.
|
|
513
|
-
const renamedFrom = document !== undefined && document.path !== target ? document : undefined;
|
|
514
|
-
if (renamedFrom !== undefined)
|
|
515
|
-
store.remove(renamedFrom.path);
|
|
516
|
-
await site.learnHandles(content.body);
|
|
517
|
-
let saved;
|
|
518
|
-
try {
|
|
519
|
-
saved = await saveDocument({ contentDir, store, path: target, content, timezone });
|
|
520
|
-
}
|
|
521
|
-
catch (error) {
|
|
522
|
-
// Nothing was written, so the row that was taken out of the way goes back.
|
|
523
|
-
if (renamedFrom !== undefined)
|
|
524
|
-
store.upsert(renamedFrom);
|
|
525
|
-
if (error instanceof DuplicatePermalinkError)
|
|
526
|
-
return refused(error.message);
|
|
527
|
-
throw error;
|
|
528
|
-
}
|
|
529
|
-
if (renamedFrom !== undefined) {
|
|
530
|
-
await rm(path.join(contentDir, ...renamedFrom.path.split('/')), { force: true });
|
|
531
|
-
}
|
|
532
|
-
if (kind.type === 'post') {
|
|
533
|
-
const locations = postLocations(config.dataDir);
|
|
534
|
-
const kept = keptProperties(config.dataDir);
|
|
535
|
-
if (document !== undefined && document.permalink !== saved.permalink) {
|
|
536
|
-
await locations.move(document.permalink, saved.permalink);
|
|
537
|
-
await kept.move(document.permalink, saved.permalink);
|
|
538
|
-
}
|
|
539
|
-
await locations.set(saved.permalink, location);
|
|
540
|
-
if (write.keptProperties !== undefined) {
|
|
541
|
-
await kept.set(saved.permalink, write.keptProperties);
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
// Announced rather than left to the watcher: the index already holds what
|
|
545
|
-
// was written, so the watcher's re-read is a no-op and nobody would ever
|
|
546
|
-
// hear that this post was published. Awaited, so a subscriber that writes
|
|
547
|
-
// back to the file — the federation stamping `activitypub` into a post it
|
|
548
|
-
// has just announced — has finished before the editor is reloaded with a
|
|
549
|
-
// hash that would otherwise be one save behind.
|
|
550
|
-
await site.announce({
|
|
551
|
-
type: document === undefined ? 'created' : 'updated',
|
|
552
|
-
path: saved.path,
|
|
553
|
-
previous: document,
|
|
554
|
-
next: saved,
|
|
555
|
-
origin: 'admin',
|
|
556
|
-
});
|
|
557
|
-
return { outcome: 'saved', saved, undescribed, respelled: tags.respelled };
|
|
558
|
-
}
|
|
559
|
-
async function citesUndescribedImage(site, document, form) {
|
|
560
|
-
if (form.previewHidden || form.citedAlt !== '' || form.title !== '')
|
|
561
|
-
return false;
|
|
562
|
-
for (const property of CITATION_PROPERTIES) {
|
|
563
|
-
const url = form[CITATION_FIELDS[property]];
|
|
564
|
-
if (url === '' || !shownInFull(property, { kind: 'photo' }))
|
|
565
|
-
continue;
|
|
566
|
-
const context = document === undefined ? await site.citedContext(url) : site.storedContext(url);
|
|
567
|
-
if (context !== undefined && citesAnImage(context))
|
|
568
|
-
return true;
|
|
569
|
-
}
|
|
570
|
-
return false;
|
|
571
|
-
}
|
|
572
|
-
/** What a save says about the images it found with no alt text, naming each. */
|
|
573
|
-
function missingAltText(images) {
|
|
574
|
-
const names = images.map((image) => image.name).join(', ');
|
|
575
|
-
const count = images.length === 1 ? '1 image has' : `${String(images.length)} images have`;
|
|
576
|
-
return (`${count} no alt text: ${names}. Describe each one inside its , ` +
|
|
577
|
-
'or mark an upload decorative in the media library.');
|
|
578
|
-
}
|
|
579
|
-
/** How many of an untitled post's first words its slug is made from. */
|
|
580
|
-
const NOTE_SLUG_WORDS = 5;
|
|
581
|
-
/** The slug a note takes from its first words, or empty when it has none. */
|
|
582
|
-
function noteSlug(body) {
|
|
583
|
-
const words = htmlToText(renderMarkdown(body)).split(' ').slice(0, NOTE_SLUG_WORDS);
|
|
584
|
-
return slugify(words.join(' '));
|
|
585
|
-
}
|
|
586
|
-
const TARGET_SLUG_WORDS = 4;
|
|
587
|
-
const CITED_SLUGS = {
|
|
588
|
-
repost: { prefix: 'reposted', field: 'repostOf' },
|
|
589
|
-
like: { prefix: 'liked', field: 'likeOf' },
|
|
590
|
-
reply: { prefix: 'reply-to', field: 'inReplyTo' },
|
|
591
|
-
rsvp: { prefix: 'rsvp', field: 'inReplyTo' },
|
|
592
|
-
bookmark: { prefix: 'bookmarked', field: 'bookmarkOf' },
|
|
593
|
-
};
|
|
594
|
-
async function typeSlug(kind, form, photos, citedContext) {
|
|
595
|
-
if (kind.type !== 'post')
|
|
596
|
-
return '';
|
|
597
|
-
const type = discoverPostType({
|
|
598
|
-
'repost-of': form.repostOf,
|
|
599
|
-
'like-of': form.likeOf,
|
|
600
|
-
'in-reply-to': form.inReplyTo,
|
|
601
|
-
rsvp: form.rsvp,
|
|
602
|
-
'bookmark-of': form.bookmarkOf,
|
|
603
|
-
photo: photos.map((photo) => photo.url),
|
|
604
|
-
});
|
|
605
|
-
if (type === 'photo')
|
|
606
|
-
return slugWords(photos[0]?.alt ?? '', NOTE_SLUG_WORDS) || 'photo';
|
|
607
|
-
const cited = CITED_SLUGS[type];
|
|
608
|
-
if (cited === undefined)
|
|
609
|
-
return '';
|
|
610
|
-
const target = form[cited.field];
|
|
611
|
-
const title = slugWords((await citedContext(target))?.name ?? '', NOTE_SLUG_WORDS);
|
|
612
|
-
return `${cited.prefix}-${title || targetWords(target)}`;
|
|
613
|
-
}
|
|
614
|
-
function targetWords(address) {
|
|
615
|
-
const url = new URL(address);
|
|
616
|
-
const segments = url.pathname.split('/').map(decodedSegment).filter(holdsALetter);
|
|
617
|
-
return slugWords([url.hostname.replace(/^www\./, ''), ...segments].join(' '), TARGET_SLUG_WORDS);
|
|
618
|
-
}
|
|
619
|
-
function slugWords(text, cap) {
|
|
620
|
-
return slugify(text).split('-').slice(0, cap).join('-');
|
|
621
|
-
}
|
|
622
|
-
function holdsALetter(segment) {
|
|
623
|
-
return /\p{L}/u.test(segment);
|
|
624
|
-
}
|
|
625
|
-
function decodedSegment(segment) {
|
|
626
|
-
try {
|
|
627
|
-
return decodeURIComponent(segment);
|
|
628
|
-
}
|
|
629
|
-
catch {
|
|
630
|
-
return segment;
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
253
|
function respelledMessage(respelled) {
|
|
634
254
|
const pairs = respelled.map(({ given, site }) => `“${site}” for “${given}”`);
|
|
635
255
|
const noun = respelled.length === 1 ? 'a tag' : `${String(respelled.length)} tags`;
|
|
@@ -649,338 +269,10 @@ function savedMessage(previous, saved, now, cited) {
|
|
|
649
269
|
return `Published: ${label}`;
|
|
650
270
|
return `Updated: ${label}`;
|
|
651
271
|
}
|
|
652
|
-
/** Where a document's file goes, trash included. */
|
|
653
|
-
function documentPath(input) {
|
|
654
|
-
const relative = contentFilePath({ type: input.kind.type, slug: input.slug, date: input.date });
|
|
655
|
-
return input.trashed ? `${TRASH_DIRECTORY}/${relative}` : relative;
|
|
656
|
-
}
|
|
657
|
-
/**
|
|
658
|
-
* The document whose URL has already been promised, or `undefined` when
|
|
659
|
-
* nothing has been promised yet.
|
|
660
|
-
*
|
|
661
|
-
* A published post or page is at a URL readers, search engines and other
|
|
662
|
-
* sites may hold, a post that was ever announced is at one its followers hold
|
|
663
|
-
* even while it is a draft, and one with comments is at the URL they were
|
|
664
|
-
* left on. A draft nobody was told about, a trashed document and one whose
|
|
665
|
-
* date has not arrived have been shown to nobody, and may move without
|
|
666
|
-
* leaving anything behind.
|
|
667
|
-
*/
|
|
668
|
-
function promisedDocument(document, now, contentDir) {
|
|
669
|
-
if (document === undefined)
|
|
670
|
-
return undefined;
|
|
671
|
-
const announced = document.activitypub?.published !== undefined;
|
|
672
|
-
const answered = existsSync(commentsFile(contentDir, document.slug));
|
|
673
|
-
return isServed(document, now) || announced || answered ? document : undefined;
|
|
674
|
-
}
|
|
675
|
-
/**
|
|
676
|
-
* The URLs a document is saved as having lived at (TASK-127).
|
|
677
|
-
*
|
|
678
|
-
* Every entry names the document itself rather than the next hop, so a chain
|
|
679
|
-
* of renames collapses by construction: the URL it is leaving joins the ones
|
|
680
|
-
* it already left, and all of them redirect straight to where it is now. The
|
|
681
|
-
* URL it is arriving at leaves the list, because a document moved back to an
|
|
682
|
-
* old URL lives there again.
|
|
683
|
-
*/
|
|
684
|
-
function formerPermalinks(document, promised, permalink) {
|
|
685
|
-
const left = promised !== undefined && promised.permalink !== permalink ? [promised.permalink] : [];
|
|
686
|
-
const former = [...new Set([...(document?.redirectFrom ?? []), ...left])].filter((url) => url !== permalink);
|
|
687
|
-
return former.length === 0 ? undefined : former;
|
|
688
|
-
}
|
|
689
|
-
/**
|
|
690
|
-
* The `activitypub` block to write, which pins the object id when a promised
|
|
691
|
-
* post moves (decision-20).
|
|
692
|
-
*
|
|
693
|
-
* decision-13 makes a post's object id its permalink, and a fediverse server
|
|
694
|
-
* cannot rename an object it holds. So the URL the post is leaving is written
|
|
695
|
-
* as its stored id, and the stored-id path does the rest: a peer at the old
|
|
696
|
-
* URL still gets the `Article`, a browser there is sent on, and every `Update`
|
|
697
|
-
* names the id the followers already have. An id the file already stores
|
|
698
|
-
* stays, since it is already what they hold.
|
|
699
|
-
*/
|
|
700
|
-
function keptIdentity(document, promised, permalink, baseUrl) {
|
|
701
|
-
const block = document?.activitypub;
|
|
702
|
-
if (promised === undefined || promised.type !== 'post' || promised.permalink === permalink) {
|
|
703
|
-
return block;
|
|
704
|
-
}
|
|
705
|
-
if (block?.id !== undefined)
|
|
706
|
-
return block;
|
|
707
|
-
return { ...block, id: absoluteUrl(promised.permalink, baseUrl) };
|
|
708
|
-
}
|
|
709
|
-
/**
|
|
710
|
-
* The extra front matter to write, which pins the feed guid when a promised
|
|
711
|
-
* page moves.
|
|
712
|
-
*
|
|
713
|
-
* A page has no object id, so its feed guid is its permalink (decision-12),
|
|
714
|
-
* and the `/replies/` feed a reader subscribed to is keyed by that guid. The
|
|
715
|
-
* URL the page is leaving is written as its stored `guid`, as a moved post's
|
|
716
|
-
* is written as its `activitypub.id`.
|
|
717
|
-
*/
|
|
718
|
-
function keptGuid(extra, promised, permalink, baseUrl) {
|
|
719
|
-
if (promised === undefined || promised.type === 'post' || promised.permalink === permalink) {
|
|
720
|
-
return extra;
|
|
721
|
-
}
|
|
722
|
-
if (extra['guid'] !== undefined)
|
|
723
|
-
return extra;
|
|
724
|
-
return { ...extra, guid: absoluteUrl(promised.permalink, baseUrl) };
|
|
725
|
-
}
|
|
726
|
-
/**
|
|
727
|
-
* The permalink to write.
|
|
728
|
-
*
|
|
729
|
-
* A permalink is explicit in the file and the stored value is what counts
|
|
730
|
-
* (doc-2), so one that was customised is never quietly rewritten. One that is
|
|
731
|
-
* still the URL its old slug and date implied follows them to the new ones,
|
|
732
|
-
* which is what makes renaming a slug in the editor do what it looks like it
|
|
733
|
-
* does.
|
|
734
|
-
*/
|
|
735
|
-
function resolvePermalink(input) {
|
|
736
|
-
const fallback = defaultPermalink({
|
|
737
|
-
type: input.kind.type,
|
|
738
|
-
slug: input.slug,
|
|
739
|
-
date: input.date,
|
|
740
|
-
});
|
|
741
|
-
const submitted = normalizePermalink(input.form.permalink);
|
|
742
|
-
if (submitted === undefined)
|
|
743
|
-
return fallback;
|
|
744
|
-
const document = input.document;
|
|
745
|
-
if (document !== undefined &&
|
|
746
|
-
submitted === previousDefaultPermalink(input.kind, document, input.timezone)) {
|
|
747
|
-
return fallback;
|
|
748
|
-
}
|
|
749
|
-
return submitted;
|
|
750
|
-
}
|
|
751
|
-
/**
|
|
752
|
-
* The permalink a document would have had if it had never been customised:
|
|
753
|
-
* its own slug over the day it is filed under, which is the day in its
|
|
754
|
-
* filename rather than one re-derived from a setting that may have moved.
|
|
755
|
-
*/
|
|
756
|
-
function previousDefaultPermalink(kind, document, timezone) {
|
|
757
|
-
try {
|
|
758
|
-
return defaultPermalink({
|
|
759
|
-
type: kind.type,
|
|
760
|
-
slug: document.slug,
|
|
761
|
-
date: filedDay({ date: document.date, document, timezone }),
|
|
762
|
-
});
|
|
763
|
-
}
|
|
764
|
-
catch {
|
|
765
|
-
return undefined;
|
|
766
|
-
}
|
|
767
|
-
}
|
|
768
|
-
/**
|
|
769
|
-
* The calendar day a document is filed under, which is what its filename and
|
|
770
|
-
* its `/{yyyy}/{mm}/` permalink are cut from.
|
|
771
|
-
*
|
|
772
|
-
* For a new document it is the day the site's own zone was on at its date, so
|
|
773
|
-
* a post published at half past midnight on 1 October in Berlin is filed under
|
|
774
|
-
* October rather than the September UTC was still on.
|
|
775
|
-
*
|
|
776
|
-
* For a document whose date has not moved it is the day already in its
|
|
777
|
-
* filename. That is the whole of decision-11's promise that changing the
|
|
778
|
-
* timezone setting cannot move an existing URL: the instant is the same, the
|
|
779
|
-
* zone is a lens, and the day this post was filed under was decided once, when
|
|
780
|
-
* it was written, and is on disk where no setting can reach it.
|
|
781
|
-
*/
|
|
782
|
-
function filedDay(input) {
|
|
783
|
-
const { document } = input;
|
|
784
|
-
const date = input.date === undefined ? undefined : toUtcInstant(input.date, input.timezone);
|
|
785
|
-
if (date === undefined)
|
|
786
|
-
return undefined;
|
|
787
|
-
const was = document?.date === undefined ? undefined : toUtcInstant(document.date, input.timezone);
|
|
788
|
-
if (was === date) {
|
|
789
|
-
const existing = /(?:^|\/)(\d{4}-\d{2}-\d{2})-/.exec(document?.path ?? '')?.[1];
|
|
790
|
-
if (existing !== undefined)
|
|
791
|
-
return existing;
|
|
792
|
-
}
|
|
793
|
-
return calendarDayIn(date, input.timezone) ?? date;
|
|
794
|
-
}
|
|
795
272
|
/** The site's time zone, which is what every offset-less date in the admin means. */
|
|
796
273
|
function siteTimezone(c) {
|
|
797
274
|
return readSiteSettings(c.var.config.contentDir).timezone;
|
|
798
275
|
}
|
|
799
|
-
/** A submitted permalink as a URL path, or `undefined` when the field is empty. */
|
|
800
|
-
function normalizePermalink(value) {
|
|
801
|
-
const trimmed = value.trim();
|
|
802
|
-
if (trimmed === '')
|
|
803
|
-
return undefined;
|
|
804
|
-
const withLeading = trimmed.startsWith('/') ? trimmed : `/${trimmed}`;
|
|
805
|
-
const last = withLeading.split('/').at(-1) ?? '';
|
|
806
|
-
// `/feed.xml` is a file and keeps its name; everything else is a directory
|
|
807
|
-
// and gets the trailing slash that is canonical here.
|
|
808
|
-
if (last === '' || last.includes('.'))
|
|
809
|
-
return withLeading;
|
|
810
|
-
return `${withLeading}/`;
|
|
811
|
-
}
|
|
812
|
-
/**
|
|
813
|
-
* The front matter to write that the CMS does not model.
|
|
814
|
-
*
|
|
815
|
-
* What the file already carried comes back out untouched, so a key somebody
|
|
816
|
-
* added by hand survives every admin save (doc-2). The one such key the editor
|
|
817
|
-
* has a field for is `eleventyExcludeFromCollections`: ticking the box writes
|
|
818
|
-
* it, and clearing the box takes the key back out rather than leaving a
|
|
819
|
-
* `false` behind — unless the file spelled the key out itself, in which case
|
|
820
|
-
* the `false` is written, because a key somebody wrote by hand is not the
|
|
821
|
-
* editor's to delete.
|
|
822
|
-
*/
|
|
823
|
-
function resolveExtra(kind, document, form, now, media, declared, timezone) {
|
|
824
|
-
const extra = { ...(document?.extra ?? {}) };
|
|
825
|
-
if (kind.type === 'post') {
|
|
826
|
-
if (media.recording === undefined)
|
|
827
|
-
delete extra[ENCLOSURE_FRONT_MATTER_KEY];
|
|
828
|
-
else
|
|
829
|
-
extra[ENCLOSURE_FRONT_MATTER_KEY] = enclosureFrontMatter(media.recording);
|
|
830
|
-
if (media.photos.length === 0)
|
|
831
|
-
delete extra[PHOTO_FRONT_MATTER_KEY];
|
|
832
|
-
else
|
|
833
|
-
extra[PHOTO_FRONT_MATTER_KEY] = photoFrontMatter(media.photos);
|
|
834
|
-
for (const property of CITATION_PROPERTIES) {
|
|
835
|
-
const cited = form[CITATION_FIELDS[property]];
|
|
836
|
-
if (cited === '')
|
|
837
|
-
delete extra[property];
|
|
838
|
-
else
|
|
839
|
-
extra[property] = cited;
|
|
840
|
-
}
|
|
841
|
-
const rsvp = rsvpValue(form.rsvp);
|
|
842
|
-
if (rsvp === undefined)
|
|
843
|
-
delete extra[RSVP_FRONT_MATTER_KEY];
|
|
844
|
-
else
|
|
845
|
-
extra[RSVP_FRONT_MATTER_KEY] = rsvp;
|
|
846
|
-
const event = resolveEvent(form.event, timezone);
|
|
847
|
-
if ('event' in event && isOrWasEvent(event.event, document)) {
|
|
848
|
-
for (const [key, value] of Object.entries(eventFrontMatter(event.event))) {
|
|
849
|
-
if (value === undefined)
|
|
850
|
-
delete extra[key];
|
|
851
|
-
else
|
|
852
|
-
extra[key] = value;
|
|
853
|
-
}
|
|
854
|
-
}
|
|
855
|
-
if (form.previewHidden)
|
|
856
|
-
extra[PREVIEW_FRONT_MATTER_KEY] = false;
|
|
857
|
-
else
|
|
858
|
-
delete extra[PREVIEW_FRONT_MATTER_KEY];
|
|
859
|
-
if (form.citedAlt === '')
|
|
860
|
-
delete extra[CITED_ALT_FRONT_MATTER_KEY];
|
|
861
|
-
else
|
|
862
|
-
extra[CITED_ALT_FRONT_MATTER_KEY] = form.citedAlt;
|
|
863
|
-
const resolved = resolveRead(form.readStatus, form.readOf);
|
|
864
|
-
if ('read' in resolved) {
|
|
865
|
-
const { read } = resolved;
|
|
866
|
-
if (read === undefined) {
|
|
867
|
-
delete extra[READ_OF_FRONT_MATTER_KEY];
|
|
868
|
-
delete extra[READ_STATUS_FRONT_MATTER_KEY];
|
|
869
|
-
}
|
|
870
|
-
else {
|
|
871
|
-
extra[READ_OF_FRONT_MATTER_KEY] = readWorkFrontMatter(read.of);
|
|
872
|
-
extra[READ_STATUS_FRONT_MATTER_KEY] = read.status;
|
|
873
|
-
}
|
|
874
|
-
}
|
|
875
|
-
}
|
|
876
|
-
// The checkboxes speak for the targets the site declares (TASK-155). An id
|
|
877
|
-
// the file lists that names no declared target has no checkbox, so it is
|
|
878
|
-
// kept as written rather than lost to a save.
|
|
879
|
-
if (kind.type === 'post') {
|
|
880
|
-
const offered = new Set(declared.map((target) => target.id));
|
|
881
|
-
const kept = syndicateToOf(extra).filter((id) => !offered.has(id));
|
|
882
|
-
// A form loaded from the file (a Micropub update) already holds those ids.
|
|
883
|
-
const listed = [...new Set([...form.syndicateTo, ...kept])];
|
|
884
|
-
if (listed.length === 0)
|
|
885
|
-
delete extra[SYNDICATE_TO_FRONT_MATTER_KEY];
|
|
886
|
-
else
|
|
887
|
-
extra[SYNDICATE_TO_FRONT_MATTER_KEY] = listed;
|
|
888
|
-
}
|
|
889
|
-
// The moment a post was pinned is what orders the featured collection, so a
|
|
890
|
-
// pin the file already carries keeps its moment through every later save,
|
|
891
|
-
// and unpinning takes the key out rather than writing `false` (TASK-207).
|
|
892
|
-
if (kind.type === 'post') {
|
|
893
|
-
const pinned = document === undefined ? undefined : pinnedAt(document);
|
|
894
|
-
if (!form.pinned)
|
|
895
|
-
delete extra[PINNED_FRONT_MATTER_KEY];
|
|
896
|
-
else if (pinned === undefined)
|
|
897
|
-
extra[PINNED_FRONT_MATTER_KEY] = toUtcInstant(now, 'UTC');
|
|
898
|
-
}
|
|
899
|
-
if (form.visibility === 'public')
|
|
900
|
-
delete extra[VISIBILITY_FRONT_MATTER_KEY];
|
|
901
|
-
else if (typeof form.visibility === 'string')
|
|
902
|
-
extra[VISIBILITY_FRONT_MATTER_KEY] = form.visibility;
|
|
903
|
-
else
|
|
904
|
-
extra[VISIBILITY_FRONT_MATTER_KEY] = form.visibility.unrecognized;
|
|
905
|
-
// Empty is the site's language, which is the key's absence (TASK-154).
|
|
906
|
-
if (form.lang === '')
|
|
907
|
-
delete extra[LANG_FRONT_MATTER_KEY];
|
|
908
|
-
else
|
|
909
|
-
extra[LANG_FRONT_MATTER_KEY] = form.lang;
|
|
910
|
-
// The post's own answer about comments, or none at all: "site default" is
|
|
911
|
-
// the absence of the key rather than a value, because that is what every
|
|
912
|
-
// reader of it — the CMS, an Eleventy build, a person looking at the file —
|
|
913
|
-
// already understands, and writing `comments: null` would say nothing new.
|
|
914
|
-
if (form.comments === COMMENT_SETTINGS.open)
|
|
915
|
-
extra[COMMENTS_FRONT_MATTER_KEY] = true;
|
|
916
|
-
else if (form.comments === COMMENT_SETTINGS.closed)
|
|
917
|
-
extra[COMMENTS_FRONT_MATTER_KEY] = false;
|
|
918
|
-
else
|
|
919
|
-
delete extra[COMMENTS_FRONT_MATTER_KEY];
|
|
920
|
-
if (kind.excludable) {
|
|
921
|
-
if (form.exclude)
|
|
922
|
-
extra[EXCLUDE_KEY] = true;
|
|
923
|
-
else if (EXCLUDE_KEY in extra)
|
|
924
|
-
extra[EXCLUDE_KEY] = false;
|
|
925
|
-
}
|
|
926
|
-
if (kind.contactable) {
|
|
927
|
-
// Written or removed, never `false`: it is the CMS's own key, and absent
|
|
928
|
-
// and false mean the same thing to everything that reads it (TASK-56).
|
|
929
|
-
if (form.contact)
|
|
930
|
-
extra[CONTACT_FRONT_MATTER_KEY] = true;
|
|
931
|
-
else
|
|
932
|
-
delete extra[CONTACT_FRONT_MATTER_KEY];
|
|
933
|
-
}
|
|
934
|
-
return extra;
|
|
935
|
-
}
|
|
936
|
-
function isOrWasEvent(saved, document) {
|
|
937
|
-
return saved !== undefined || (document !== undefined && eventOf(document.extra) !== undefined);
|
|
938
|
-
}
|
|
939
|
-
/** The editor checkbox that selects one syndication target. */
|
|
940
|
-
function syndicateToField(target) {
|
|
941
|
-
return `${SYNDICATE_TO_FRONT_MATTER_KEY}-${target.id}`;
|
|
942
|
-
}
|
|
943
|
-
/**
|
|
944
|
-
* A comma-separated taxonomy field as a list, without the blanks and the
|
|
945
|
-
* repeats. Tags and categories are both entered this way.
|
|
946
|
-
*/
|
|
947
|
-
export function splitTags(value) {
|
|
948
|
-
const tags = [];
|
|
949
|
-
for (const tag of value.split(',')) {
|
|
950
|
-
const trimmed = tag.trim();
|
|
951
|
-
if (trimmed !== '' && !tags.includes(trimmed))
|
|
952
|
-
tags.push(trimmed);
|
|
953
|
-
}
|
|
954
|
-
return tags;
|
|
955
|
-
}
|
|
956
|
-
/** The signed-in user's login, which is what doc-2's `author` holds. */
|
|
957
|
-
function currentUsername(c) {
|
|
958
|
-
const userId = c.var.session?.userId;
|
|
959
|
-
if (userId == null)
|
|
960
|
-
return undefined;
|
|
961
|
-
return findUserById(c.var.config.dataDir, userId)?.username;
|
|
962
|
-
}
|
|
963
|
-
/**
|
|
964
|
-
* What a save writes into the front matter's `author`.
|
|
965
|
-
*
|
|
966
|
-
* The submitted value is resolved through the same rule the public site reads
|
|
967
|
-
* it by ({@link userForAuthor}), and what is written is that user's login: so
|
|
968
|
-
* a file carrying a display name from before decision-14 is rewritten as a
|
|
969
|
-
* username the first time somebody saves it, which is exactly the "until it is
|
|
970
|
-
* next saved" doc-2 promises.
|
|
971
|
-
*
|
|
972
|
-
* A value naming nobody this site has changes nothing. There is no form this
|
|
973
|
-
* CMS renders that could submit one — the select only ever offers the users
|
|
974
|
-
* and, for a file that names a stranger, that file's own value — so the case
|
|
975
|
-
* is either a hand-made request or a user deleted between the load and the
|
|
976
|
-
* save, and neither is a reason to reattribute somebody's post.
|
|
977
|
-
*/
|
|
978
|
-
function chosenAuthor(dataDir, submitted, document, writer) {
|
|
979
|
-
const named = userForAuthor(listUsers(dataDir), submitted);
|
|
980
|
-
if (named !== undefined)
|
|
981
|
-
return named.username;
|
|
982
|
-
return document?.author ?? writer;
|
|
983
|
-
}
|
|
984
276
|
/**
|
|
985
277
|
* The Author select: every user, whoever the document names, and — for a file
|
|
986
278
|
* naming somebody with no account here — that name too.
|
|
@@ -997,7 +289,7 @@ function chosenAuthor(dataDir, submitted, document, writer) {
|
|
|
997
289
|
export function authorChoices(c, current) {
|
|
998
290
|
const users = listUsers(c.var.config.dataDir);
|
|
999
291
|
const named = userForAuthor(users, current);
|
|
1000
|
-
const chosen = named?.username ?? (current ===
|
|
292
|
+
const chosen = named?.username ?? (current === AUTHOR_UNTIL_REQUEST ? currentUsername(c) : current);
|
|
1001
293
|
const choices = users.map((user) => ({
|
|
1002
294
|
value: user.username,
|
|
1003
295
|
label: authorLabel(user),
|
|
@@ -1005,7 +297,7 @@ export function authorChoices(c, current) {
|
|
|
1005
297
|
}));
|
|
1006
298
|
// A name the file holds that is nobody here: offered last, and marked, so it
|
|
1007
299
|
// is plain that the post is attributed to somebody this site cannot reach.
|
|
1008
|
-
if (named === undefined && current !==
|
|
300
|
+
if (named === undefined && current !== AUTHOR_UNTIL_REQUEST) {
|
|
1009
301
|
choices.push({ value: current, label: `${current} (no account here)`, chosen: true });
|
|
1010
302
|
}
|
|
1011
303
|
return choices;
|
|
@@ -1015,36 +307,6 @@ function authorLabel(user) {
|
|
|
1015
307
|
const displayName = user.profile?.displayName;
|
|
1016
308
|
return displayName === undefined ? user.username : `${displayName} (${user.username})`;
|
|
1017
309
|
}
|
|
1018
|
-
/**
|
|
1019
|
-
* Whether the file has moved on since the form loaded, per doc-1: files win,
|
|
1020
|
-
* and an edit made behind the editor's back is never silently overwritten.
|
|
1021
|
-
*
|
|
1022
|
-
* The file is read and re-parsed rather than trusted to the index, so the
|
|
1023
|
-
* check is right even when the watcher is off or has not caught up.
|
|
1024
|
-
*/
|
|
1025
|
-
async function conflictWith(contentDir, document, submittedHash) {
|
|
1026
|
-
const file = path.join(contentDir, ...document.path.split('/'));
|
|
1027
|
-
let source;
|
|
1028
|
-
try {
|
|
1029
|
-
source = await readFile(file, 'utf8');
|
|
1030
|
-
}
|
|
1031
|
-
catch {
|
|
1032
|
-
// The file is gone. There is nothing to lose by writing it again.
|
|
1033
|
-
return undefined;
|
|
1034
|
-
}
|
|
1035
|
-
let hash;
|
|
1036
|
-
try {
|
|
1037
|
-
hash = parseDocument(source, { path: document.path, type: document.type }).hash;
|
|
1038
|
-
}
|
|
1039
|
-
catch {
|
|
1040
|
-
// A file that will not parse cannot be compared, and overwriting it would
|
|
1041
|
-
// throw away whatever is wrong with it before anyone has seen it.
|
|
1042
|
-
hash = '';
|
|
1043
|
-
}
|
|
1044
|
-
if (hash === submittedHash)
|
|
1045
|
-
return undefined;
|
|
1046
|
-
return { current: source, hash };
|
|
1047
|
-
}
|
|
1048
310
|
/**
|
|
1049
311
|
* The refused save, side by side with the file it would have overwritten.
|
|
1050
312
|
*
|
|
@@ -1054,6 +316,7 @@ async function conflictWith(contentDir, document, submittedHash) {
|
|
|
1054
316
|
*/
|
|
1055
317
|
function renderConflict(c, options) {
|
|
1056
318
|
const { kind, document, form, conflict } = options;
|
|
319
|
+
const inReplyTo = formInReplyTo(kind, form, document);
|
|
1057
320
|
const submitted = serializeDocument({
|
|
1058
321
|
title: form.title,
|
|
1059
322
|
...(form.date === '' ? {} : { date: form.date }),
|
|
@@ -1062,10 +325,10 @@ function renderConflict(c, options) {
|
|
|
1062
325
|
categories: kind.categorised ? splitTags(form.categories) : [],
|
|
1063
326
|
draft: form.draft,
|
|
1064
327
|
...(form.description === '' ? {} : { description: form.description }),
|
|
1065
|
-
...
|
|
1066
|
-
...
|
|
1067
|
-
...
|
|
1068
|
-
extra:
|
|
328
|
+
...(document.author === undefined ? {} : { author: document.author }),
|
|
329
|
+
...(inReplyTo === undefined ? {} : { inReplyTo }),
|
|
330
|
+
...(document.activitypub === undefined ? {} : { activitypub: document.activitypub }),
|
|
331
|
+
extra: extraFromForm(kind, document, form, c.var.store.now(), options.media, syndicationTargetsReader(c.var.config.contentDir)(), siteTimezone(c)),
|
|
1069
332
|
body: form.body,
|
|
1070
333
|
});
|
|
1071
334
|
c.status(409);
|
|
@@ -1105,91 +368,6 @@ async function moveDocument(c, options) {
|
|
|
1105
368
|
return c.redirect(returnPath(options.returnTo) ??
|
|
1106
369
|
(action === 'trash' ? kind.basePath : documentEditorPath(kind, moved.document)), 303);
|
|
1107
370
|
}
|
|
1108
|
-
/**
|
|
1109
|
-
* Move a document into `content/_trash/` or back out of it, the move behind
|
|
1110
|
-
* the editor's trash and restore and Micropub's delete and undelete
|
|
1111
|
-
* (TASK-167).
|
|
1112
|
-
*
|
|
1113
|
-
* The trash mirrors the content tree — `posts/2026-03-04-x.md` becomes
|
|
1114
|
-
* `_trash/posts/2026-03-04-x.md` — so restoring is the same move backwards and
|
|
1115
|
-
* needs to remember nothing. The index is corrected as soon as the file has
|
|
1116
|
-
* landed rather than waiting for the watcher, so the public site stops or
|
|
1117
|
-
* starts serving the document with this request (doc-1).
|
|
1118
|
-
*
|
|
1119
|
-
* A live document may take a trashed one's URL, and its file name with it
|
|
1120
|
-
* (TASK-195). So a restore that would land on either is refused, and a trashed
|
|
1121
|
-
* file already at the name is kept by numbering the newcomer: the permalink in
|
|
1122
|
-
* the front matter, not the file name, is what the document answers at.
|
|
1123
|
-
*/
|
|
1124
|
-
export async function moveDocumentFile(site, document, action) {
|
|
1125
|
-
const { store, contentDir } = site;
|
|
1126
|
-
let target;
|
|
1127
|
-
if (action === 'trash') {
|
|
1128
|
-
target = await freeTrashPath(contentDir, document.path);
|
|
1129
|
-
}
|
|
1130
|
-
else {
|
|
1131
|
-
target = document.path
|
|
1132
|
-
.split('/')
|
|
1133
|
-
.filter((segment) => segment !== TRASH_DIRECTORY)
|
|
1134
|
-
.join('/');
|
|
1135
|
-
const holder = store.getByPermalink(document.permalink);
|
|
1136
|
-
if (holder !== undefined && !isTrashedPath(holder.path)) {
|
|
1137
|
-
return refusedMove(`${holder.path} now holds ${document.permalink}, so this cannot go back there. ` +
|
|
1138
|
-
'Change one of their permalinks first.');
|
|
1139
|
-
}
|
|
1140
|
-
if (await exists(path.join(contentDir, ...target.split('/')))) {
|
|
1141
|
-
return refusedMove(`${target} already exists, so this cannot go back there.`);
|
|
1142
|
-
}
|
|
1143
|
-
}
|
|
1144
|
-
const from = path.join(contentDir, ...document.path.split('/'));
|
|
1145
|
-
const to = path.join(contentDir, ...target.split('/'));
|
|
1146
|
-
let source;
|
|
1147
|
-
try {
|
|
1148
|
-
source = await readFile(from, 'utf8');
|
|
1149
|
-
await mkdir(path.dirname(to), { recursive: true });
|
|
1150
|
-
await rename(from, to);
|
|
1151
|
-
}
|
|
1152
|
-
catch {
|
|
1153
|
-
return refusedMove(`Could not move ${document.path}. Is the file still there?`);
|
|
1154
|
-
}
|
|
1155
|
-
const moved = parseDocument(source, {
|
|
1156
|
-
path: target,
|
|
1157
|
-
type: document.type,
|
|
1158
|
-
handles: handleDirectory(contentDir),
|
|
1159
|
-
});
|
|
1160
|
-
store.remove(document.path);
|
|
1161
|
-
store.upsert(moved);
|
|
1162
|
-
// Trashing takes a post off the public site and restoring puts it back, so
|
|
1163
|
-
// both are visibility changes a subscriber has to hear about.
|
|
1164
|
-
await site.announce({
|
|
1165
|
-
type: 'updated',
|
|
1166
|
-
path: target,
|
|
1167
|
-
previous: document,
|
|
1168
|
-
next: moved,
|
|
1169
|
-
origin: 'admin',
|
|
1170
|
-
});
|
|
1171
|
-
return { outcome: 'moved', document: moved };
|
|
1172
|
-
}
|
|
1173
|
-
function refusedMove(reason) {
|
|
1174
|
-
return { outcome: 'refused', reason };
|
|
1175
|
-
}
|
|
1176
|
-
async function freeTrashPath(contentDir, relative) {
|
|
1177
|
-
const { dir, name, ext } = path.posix.parse(`${TRASH_DIRECTORY}/${relative}`);
|
|
1178
|
-
for (let suffix = 1;; suffix += 1) {
|
|
1179
|
-
const candidate = `${dir}/${name}${suffix === 1 ? '' : `-${String(suffix)}`}${ext}`;
|
|
1180
|
-
if (!(await exists(path.join(contentDir, ...candidate.split('/')))))
|
|
1181
|
-
return candidate;
|
|
1182
|
-
}
|
|
1183
|
-
}
|
|
1184
|
-
async function exists(file) {
|
|
1185
|
-
try {
|
|
1186
|
-
await access(file);
|
|
1187
|
-
return true;
|
|
1188
|
-
}
|
|
1189
|
-
catch {
|
|
1190
|
-
return false;
|
|
1191
|
-
}
|
|
1192
|
-
}
|
|
1193
371
|
/** Report a move that did not happen and go back where the form came from. */
|
|
1194
372
|
function backTo(c, options, message) {
|
|
1195
373
|
flash(c, 'error', message);
|
|
@@ -1209,142 +387,6 @@ export function returnPath(value) {
|
|
|
1209
387
|
return undefined;
|
|
1210
388
|
return trimmed;
|
|
1211
389
|
}
|
|
1212
|
-
function optional(key, value) {
|
|
1213
|
-
return value === undefined ? {} : { [key]: value };
|
|
1214
|
-
}
|
|
1215
|
-
/** A form field as a string. A file upload, or a missing field, is the empty one. */
|
|
1216
|
-
function text(value) {
|
|
1217
|
-
return typeof value === 'string' ? value : '';
|
|
1218
|
-
}
|
|
1219
|
-
/**
|
|
1220
|
-
* The `in-reply-to` a save writes: the field for a post, where an empty one
|
|
1221
|
-
* clears it, and whatever the file had for a page, whose editor has no field.
|
|
1222
|
-
*/
|
|
1223
|
-
function replyTo(kind, form, document) {
|
|
1224
|
-
if (kind.type !== 'post')
|
|
1225
|
-
return document?.inReplyTo;
|
|
1226
|
-
return form.inReplyTo === '' ? undefined : form.inReplyTo;
|
|
1227
|
-
}
|
|
1228
|
-
/**
|
|
1229
|
-
* The editor field each citing property fills (TASK-169). The form submits it
|
|
1230
|
-
* under the property's own name, as `in-reply-to` is.
|
|
1231
|
-
*/
|
|
1232
|
-
export const CITATION_FIELDS = {
|
|
1233
|
-
'repost-of': 'repostOf',
|
|
1234
|
-
'like-of': 'likeOf',
|
|
1235
|
-
'bookmark-of': 'bookmarkOf',
|
|
1236
|
-
};
|
|
1237
|
-
/** What the editor calls each citing field, which a refusal names. */
|
|
1238
|
-
const CITATION_LABELS = {
|
|
1239
|
-
'repost-of': 'Repost of',
|
|
1240
|
-
'like-of': 'Like of',
|
|
1241
|
-
'bookmark-of': 'Bookmark of',
|
|
1242
|
-
};
|
|
1243
|
-
/** The three citing fields, each filled from its property. */
|
|
1244
|
-
function citationFields(value) {
|
|
1245
|
-
return {
|
|
1246
|
-
repostOf: value('repost-of'),
|
|
1247
|
-
likeOf: value('like-of'),
|
|
1248
|
-
bookmarkOf: value('bookmark-of'),
|
|
1249
|
-
};
|
|
1250
|
-
}
|
|
1251
|
-
/**
|
|
1252
|
-
* The editor for a document that does not exist yet.
|
|
1253
|
-
*
|
|
1254
|
-
* The date field is filled in with the clock as the site's own zone reads it,
|
|
1255
|
-
* not with an instant: what a form offers is what a form takes back, and per
|
|
1256
|
-
* decision-11 an offset-less date in this field means the site's zone.
|
|
1257
|
-
*/
|
|
1258
|
-
export function blankForm(kind, timezone = DEFAULT_TIMEZONE, now = new Date()) {
|
|
1259
|
-
return {
|
|
1260
|
-
title: '',
|
|
1261
|
-
slug: '',
|
|
1262
|
-
permalink: '',
|
|
1263
|
-
date: kind.dated ? wallClockIn(now, timezone) : '',
|
|
1264
|
-
tags: '',
|
|
1265
|
-
categories: '',
|
|
1266
|
-
description: '',
|
|
1267
|
-
// Empty rather than the signed-in user: `blankForm` is a pure function
|
|
1268
|
-
// over a kind and a clock, and who is signed in is a fact about a request.
|
|
1269
|
-
// {@link authorChoices} is where the default is applied.
|
|
1270
|
-
author: '',
|
|
1271
|
-
inReplyTo: '',
|
|
1272
|
-
rsvp: '',
|
|
1273
|
-
...citationFields(() => ''),
|
|
1274
|
-
readStatus: '',
|
|
1275
|
-
readOf: BLANK_READ_OF_FORM,
|
|
1276
|
-
event: BLANK_EVENT_FORM,
|
|
1277
|
-
lang: '',
|
|
1278
|
-
draft: false,
|
|
1279
|
-
visibility: 'public',
|
|
1280
|
-
exclude: false,
|
|
1281
|
-
contact: false,
|
|
1282
|
-
pinned: false,
|
|
1283
|
-
previewHidden: false,
|
|
1284
|
-
citedAlt: '',
|
|
1285
|
-
comments: COMMENT_SETTINGS.site,
|
|
1286
|
-
enclosure: BLANK_ENCLOSURE_FORM,
|
|
1287
|
-
photos: [],
|
|
1288
|
-
location: BLANK_LOCATION_FORM,
|
|
1289
|
-
syndicateTo: [],
|
|
1290
|
-
body: '',
|
|
1291
|
-
hash: '',
|
|
1292
|
-
};
|
|
1293
|
-
}
|
|
1294
|
-
/**
|
|
1295
|
-
* The editor for a document that does.
|
|
1296
|
-
*
|
|
1297
|
-
* The stored instant is shown as the clock in the site's zone reads it, and
|
|
1298
|
-
* {@link wallClockIn} keeps whatever precision the instant has, so a form
|
|
1299
|
-
* submitted with the field untouched writes back the very instant it was
|
|
1300
|
-
* filled in from.
|
|
1301
|
-
*
|
|
1302
|
-
* `location` is what `data/locations.json` holds for the post (decision-29),
|
|
1303
|
-
* which a document does not carry. It is required because a form loaded
|
|
1304
|
-
* without it would remove the stored location on save.
|
|
1305
|
-
*/
|
|
1306
|
-
export function formFor(document, timezone, location) {
|
|
1307
|
-
return {
|
|
1308
|
-
title: document.title,
|
|
1309
|
-
slug: document.slug,
|
|
1310
|
-
permalink: document.permalink,
|
|
1311
|
-
date: document.date === undefined ? '' : wallClockIn(document.date, timezone),
|
|
1312
|
-
tags: document.tags.join(', '),
|
|
1313
|
-
categories: document.categories.join(', '),
|
|
1314
|
-
description: document.description ?? '',
|
|
1315
|
-
author: document.author ?? '',
|
|
1316
|
-
inReplyTo: document.inReplyTo ?? '',
|
|
1317
|
-
rsvp: document.type === 'post' && typeof document.extra[RSVP_FRONT_MATTER_KEY] === 'string'
|
|
1318
|
-
? document.extra[RSVP_FRONT_MATTER_KEY]
|
|
1319
|
-
: '',
|
|
1320
|
-
// As the file spells it, so a save writes back what it read.
|
|
1321
|
-
...citationFields((property) => document.type === 'post' ? citationText(document.extra[property]) : ''),
|
|
1322
|
-
readStatus: document.type === 'post' && typeof document.extra[READ_STATUS_FRONT_MATTER_KEY] === 'string'
|
|
1323
|
-
? document.extra[READ_STATUS_FRONT_MATTER_KEY]
|
|
1324
|
-
: '',
|
|
1325
|
-
readOf: readOfForm(document.type === 'post' ? readWork(document.extra[READ_OF_FRONT_MATTER_KEY]) : undefined),
|
|
1326
|
-
event: document.type === 'post' ? eventForm(document.extra, timezone) : BLANK_EVENT_FORM,
|
|
1327
|
-
lang: typeof document.extra[LANG_FRONT_MATTER_KEY] === 'string'
|
|
1328
|
-
? document.extra[LANG_FRONT_MATTER_KEY]
|
|
1329
|
-
: '',
|
|
1330
|
-
draft: document.draft,
|
|
1331
|
-
visibility: visibilityOf(document),
|
|
1332
|
-
exclude: document.extra[EXCLUDE_KEY] === true,
|
|
1333
|
-
contact: document.extra[CONTACT_FRONT_MATTER_KEY] === true,
|
|
1334
|
-
pinned: pinnedAt(document) !== undefined,
|
|
1335
|
-
previewHidden: document.type === 'post' && !previewShown(document.extra),
|
|
1336
|
-
citedAlt: document.type === 'post' && typeof document.extra[CITED_ALT_FRONT_MATTER_KEY] === 'string'
|
|
1337
|
-
? document.extra[CITED_ALT_FRONT_MATTER_KEY]
|
|
1338
|
-
: '',
|
|
1339
|
-
comments: commentSettingOf(document),
|
|
1340
|
-
enclosure: document.type === 'post' ? enclosureForm(document) : BLANK_ENCLOSURE_FORM,
|
|
1341
|
-
photos: document.type === 'post' ? photoRows(document) : [],
|
|
1342
|
-
location: document.type === 'post' ? locationForm(location) : BLANK_LOCATION_FORM,
|
|
1343
|
-
syndicateTo: document.type === 'post' ? syndicateToOf(document.extra) : [],
|
|
1344
|
-
body: document.body,
|
|
1345
|
-
hash: document.hash,
|
|
1346
|
-
};
|
|
1347
|
-
}
|
|
1348
390
|
/**
|
|
1349
391
|
* The editor screen.
|
|
1350
392
|
*
|
|
@@ -1376,7 +418,7 @@ async function renderEditor(c, options) {
|
|
|
1376
418
|
if (options.status !== undefined)
|
|
1377
419
|
c.status(options.status);
|
|
1378
420
|
const permissions = c.var.config.securityHeaders['permissions-policy'];
|
|
1379
|
-
if (kind.
|
|
421
|
+
if (kind.located && permissions !== undefined) {
|
|
1380
422
|
c.header('Permissions-Policy', allowGeolocation(permissions));
|
|
1381
423
|
}
|
|
1382
424
|
return options.render(c, ADMIN_TEMPLATES.documentEditor, {
|
|
@@ -1433,7 +475,7 @@ async function renderEditor(c, options) {
|
|
|
1433
475
|
viewUrl: document !== undefined && isServed(document, now) ? document.permalink : undefined,
|
|
1434
476
|
// Named beside the date field, because a wall clock with no zone on it is
|
|
1435
477
|
// exactly the ambiguity decision-11 exists to remove.
|
|
1436
|
-
...(kind.dated ? { dateZone: zoneLabel(form.date
|
|
478
|
+
...(kind.dated ? { dateZone: zoneLabel(form.date, timezone, now) } : {}),
|
|
1437
479
|
...(scheduledAt === undefined ? {} : { scheduledFor: formatInTimezone(scheduledAt, timezone) }),
|
|
1438
480
|
...(options.refusal === undefined
|
|
1439
481
|
? {}
|