@geekity/cms 0.31.0 → 0.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/admin/components/badge.njk +4 -0
- package/admin/components/fields.njk +41 -24
- package/admin/components/job-status.njk +45 -0
- package/admin/components/setting-fields.njk +38 -0
- package/admin/layouts/settings-page.njk +16 -0
- package/admin/pages/comments/all.njk +1 -2
- package/admin/pages/documents/editor.njk +17 -15
- package/admin/pages/documents/syndication.njk +4 -4
- package/admin/pages/federation/followers.njk +56 -6
- package/admin/pages/federation/settings.njk +1 -1
- package/admin/pages/media/library.njk +52 -3
- package/admin/pages/navigation/menus.njk +2 -2
- package/admin/pages/plugins/screen.njk +5 -46
- package/admin/pages/settings/discussion.njk +76 -47
- package/admin/pages/settings/email.njk +75 -47
- package/admin/pages/settings/general.njk +15 -15
- package/admin/pages/settings/permalinks.njk +8 -8
- package/admin/pages/settings/privacy.njk +6 -6
- package/admin/pages/settings/reading.njk +36 -36
- package/admin/pages/tools/dev-mode.njk +29 -3
- package/admin/pages/tools/export.njk +89 -0
- package/admin/pages/tools/maintenance.njk +51 -0
- package/admin/pages/users/apps.njk +2 -2
- package/admin/pages/users/edit.njk +3 -3
- package/admin/pages/users/new.njk +2 -2
- package/admin/static/admin.css +80 -0
- package/dist/admin/app-activity.d.ts.map +1 -1
- package/dist/admin/app-activity.js +2 -3
- package/dist/admin/app-activity.js.map +1 -1
- package/dist/admin/appearance.d.ts +1 -5
- package/dist/admin/appearance.d.ts.map +1 -1
- package/dist/admin/appearance.js +9 -16
- package/dist/admin/appearance.js.map +1 -1
- package/dist/admin/comments.d.ts.map +1 -1
- package/dist/admin/comments.js +2 -3
- package/dist/admin/comments.js.map +1 -1
- package/dist/admin/confirm-password.d.ts +4 -0
- package/dist/admin/confirm-password.d.ts.map +1 -0
- package/dist/admin/confirm-password.js +11 -0
- package/dist/admin/confirm-password.js.map +1 -0
- package/dist/admin/connected-apps.d.ts.map +1 -1
- package/dist/admin/connected-apps.js +17 -22
- package/dist/admin/connected-apps.js.map +1 -1
- package/dist/admin/dev-mode.d.ts.map +1 -1
- package/dist/admin/dev-mode.js +35 -10
- package/dist/admin/dev-mode.js.map +1 -1
- package/dist/admin/documents.d.ts.map +1 -1
- package/dist/admin/documents.js +22 -10
- package/dist/admin/documents.js.map +1 -1
- package/dist/admin/editor-actions.d.ts.map +1 -1
- package/dist/admin/editor-actions.js +1 -2
- package/dist/admin/editor-actions.js.map +1 -1
- package/dist/admin/editor-layout.js +1 -1
- package/dist/admin/editor-layout.js.map +1 -1
- package/dist/admin/export.d.ts +10 -0
- package/dist/admin/export.d.ts.map +1 -0
- package/dist/admin/export.js +72 -0
- package/dist/admin/export.js.map +1 -0
- package/dist/admin/federation.d.ts +1 -12
- package/dist/admin/federation.d.ts.map +1 -1
- package/dist/admin/federation.js +34 -87
- package/dist/admin/federation.js.map +1 -1
- package/dist/admin/index.d.ts +2 -5
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +2 -4
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/indieauth-consent.d.ts.map +1 -1
- package/dist/admin/indieauth-consent.js +5 -7
- package/dist/admin/indieauth-consent.js.map +1 -1
- package/dist/admin/job-status.d.ts +25 -0
- package/dist/admin/job-status.d.ts.map +1 -0
- package/dist/admin/job-status.js +53 -0
- package/dist/admin/job-status.js.map +1 -0
- package/dist/admin/legacy-migrations.d.ts.map +1 -1
- package/dist/admin/legacy-migrations.js +7 -6
- package/dist/admin/legacy-migrations.js.map +1 -1
- package/dist/admin/maintenance.d.ts +9 -0
- package/dist/admin/maintenance.d.ts.map +1 -0
- package/dist/admin/maintenance.js +42 -0
- package/dist/admin/maintenance.js.map +1 -0
- package/dist/admin/media.d.ts +4 -1
- package/dist/admin/media.d.ts.map +1 -1
- package/dist/admin/media.js +16 -1
- package/dist/admin/media.js.map +1 -1
- package/dist/admin/menu.d.ts.map +1 -1
- package/dist/admin/menu.js +4 -0
- package/dist/admin/menu.js.map +1 -1
- package/dist/admin/messages.d.ts.map +1 -1
- package/dist/admin/messages.js +2 -3
- package/dist/admin/messages.js.map +1 -1
- package/dist/admin/navigation.d.ts.map +1 -1
- package/dist/admin/navigation.js +27 -23
- package/dist/admin/navigation.js.map +1 -1
- package/dist/admin/plugins.d.ts.map +1 -1
- package/dist/admin/plugins.js +19 -66
- package/dist/admin/plugins.js.map +1 -1
- package/dist/admin/preview.d.ts.map +1 -1
- package/dist/admin/preview.js +5 -6
- package/dist/admin/preview.js.map +1 -1
- package/dist/admin/recovery.js +2 -2
- package/dist/admin/recovery.js.map +1 -1
- package/dist/admin/routes.d.ts.map +1 -1
- package/dist/admin/routes.js +6 -3
- package/dist/admin/routes.js.map +1 -1
- package/dist/admin/setting-overrides.d.ts +4 -0
- package/dist/admin/setting-overrides.d.ts.map +1 -0
- package/dist/admin/setting-overrides.js +24 -0
- package/dist/admin/setting-overrides.js.map +1 -0
- package/dist/admin/settings-discussion.d.ts +6 -4
- package/dist/admin/settings-discussion.d.ts.map +1 -1
- package/dist/admin/settings-discussion.js +75 -45
- package/dist/admin/settings-discussion.js.map +1 -1
- package/dist/admin/settings-email.d.ts +11 -8
- package/dist/admin/settings-email.d.ts.map +1 -1
- package/dist/admin/settings-email.js +88 -77
- package/dist/admin/settings-email.js.map +1 -1
- package/dist/admin/settings-federation.d.ts +0 -7
- package/dist/admin/settings-federation.d.ts.map +1 -1
- package/dist/admin/settings-federation.js +0 -36
- package/dist/admin/settings-federation.js.map +1 -1
- package/dist/admin/settings-fields.d.ts +32 -0
- package/dist/admin/settings-fields.d.ts.map +1 -0
- package/dist/admin/settings-fields.js +368 -0
- package/dist/admin/settings-fields.js.map +1 -0
- package/dist/admin/settings-general.d.ts.map +1 -1
- package/dist/admin/settings-general.js +10 -19
- package/dist/admin/settings-general.js.map +1 -1
- package/dist/admin/settings-page.d.ts +3 -29
- package/dist/admin/settings-page.d.ts.map +1 -1
- package/dist/admin/settings-page.js +38 -53
- package/dist/admin/settings-page.js.map +1 -1
- package/dist/admin/settings-permalinks.js +2 -2
- package/dist/admin/settings-permalinks.js.map +1 -1
- package/dist/admin/settings-privacy.js +1 -1
- package/dist/admin/settings-privacy.js.map +1 -1
- package/dist/admin/settings-reading.js +13 -13
- package/dist/admin/settings-reading.js.map +1 -1
- package/dist/admin/settings-renderer.d.ts +32 -0
- package/dist/admin/settings-renderer.d.ts.map +1 -0
- package/dist/admin/settings-renderer.js +79 -0
- package/dist/admin/settings-renderer.js.map +1 -0
- package/dist/admin/site-setting-edit.d.ts +4 -0
- package/dist/admin/site-setting-edit.d.ts.map +1 -0
- package/dist/admin/site-setting-edit.js +20 -0
- package/dist/admin/site-setting-edit.js.map +1 -0
- package/dist/admin/taxonomy.d.ts.map +1 -1
- package/dist/admin/taxonomy.js +10 -19
- package/dist/admin/taxonomy.js.map +1 -1
- package/dist/admin/templates.d.ts +2 -0
- package/dist/admin/templates.d.ts.map +1 -1
- package/dist/admin/templates.js +2 -0
- package/dist/admin/templates.js.map +1 -1
- package/dist/admin/users.js +1 -1
- package/dist/admin/users.js.map +1 -1
- package/dist/avatars/avatars.d.ts +0 -2
- package/dist/avatars/avatars.d.ts.map +1 -1
- package/dist/avatars/avatars.js +9 -10
- package/dist/avatars/avatars.js.map +1 -1
- package/dist/avatars/index.d.ts +1 -1
- package/dist/avatars/index.d.ts.map +1 -1
- package/dist/avatars/index.js +1 -1
- package/dist/avatars/index.js.map +1 -1
- package/dist/cache.d.ts +0 -2
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js +2 -4
- package/dist/cache.js.map +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +500 -86
- package/dist/cli.js.map +1 -1
- package/dist/cms/app.d.ts +1 -1
- package/dist/cms/app.d.ts.map +1 -1
- package/dist/cms/app.js +13 -2
- package/dist/cms/app.js.map +1 -1
- package/dist/cms/boot.d.ts +12 -0
- package/dist/cms/boot.d.ts.map +1 -1
- package/dist/cms/boot.js +37 -16
- package/dist/cms/boot.js.map +1 -1
- package/dist/cms/create.d.ts +24 -0
- package/dist/cms/create.d.ts.map +1 -1
- package/dist/cms/create.js +14 -0
- package/dist/cms/create.js.map +1 -1
- package/dist/cms/services.d.ts +3 -1
- package/dist/cms/services.d.ts.map +1 -1
- package/dist/cms/services.js +83 -26
- package/dist/cms/services.js.map +1 -1
- package/dist/cms/site-records.d.ts.map +1 -1
- package/dist/cms/site-records.js +0 -2
- package/dist/cms/site-records.js.map +1 -1
- package/dist/comments/akismet.d.ts +13 -46
- package/dist/comments/akismet.d.ts.map +1 -1
- package/dist/comments/akismet.js +29 -68
- package/dist/comments/akismet.js.map +1 -1
- package/dist/comments/conversation.d.ts +14 -8
- package/dist/comments/conversation.d.ts.map +1 -1
- package/dist/comments/conversation.js.map +1 -1
- package/dist/comments/index.d.ts +4 -4
- package/dist/comments/index.d.ts.map +1 -1
- package/dist/comments/index.js +3 -3
- package/dist/comments/index.js.map +1 -1
- package/dist/comments/policy.d.ts +23 -26
- package/dist/comments/policy.d.ts.map +1 -1
- package/dist/comments/policy.js +13 -20
- package/dist/comments/policy.js.map +1 -1
- package/dist/comments/records.d.ts +0 -2
- package/dist/comments/records.d.ts.map +1 -1
- package/dist/comments/records.js +2 -3
- package/dist/comments/records.js.map +1 -1
- package/dist/comments/reply-notices.d.ts +5 -6
- package/dist/comments/reply-notices.d.ts.map +1 -1
- package/dist/comments/reply-notices.js +27 -15
- package/dist/comments/reply-notices.js.map +1 -1
- package/dist/comments/reply-post.d.ts.map +1 -1
- package/dist/comments/reply-post.js +2 -3
- package/dist/comments/reply-post.js.map +1 -1
- package/dist/comments/submission.d.ts +0 -2
- package/dist/comments/submission.d.ts.map +1 -1
- package/dist/comments/submission.js +1 -3
- package/dist/comments/submission.js.map +1 -1
- package/dist/config-loader.d.ts.map +1 -1
- package/dist/config-loader.js +2 -1
- package/dist/config-loader.js.map +1 -1
- package/dist/config.d.ts +27 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +5 -1
- package/dist/config.js.map +1 -1
- package/dist/contact/delivery.d.ts +2 -4
- package/dist/contact/delivery.d.ts.map +1 -1
- package/dist/contact/delivery.js +1 -2
- package/dist/contact/delivery.js.map +1 -1
- package/dist/contact/index.d.ts +1 -1
- package/dist/contact/index.d.ts.map +1 -1
- package/dist/contact/index.js +1 -1
- package/dist/contact/index.js.map +1 -1
- package/dist/contact/records.d.ts +0 -2
- package/dist/contact/records.d.ts.map +1 -1
- package/dist/contact/records.js +3 -5
- package/dist/contact/records.js.map +1 -1
- package/dist/content/citation.d.ts +1 -0
- package/dist/content/citation.d.ts.map +1 -1
- package/dist/content/citation.js.map +1 -1
- package/dist/content/document-form.d.ts +3 -1
- package/dist/content/document-form.d.ts.map +1 -1
- package/dist/content/document-form.js.map +1 -1
- package/dist/content/enclosure-form.d.ts.map +1 -1
- package/dist/content/enclosure-form.js +5 -6
- package/dist/content/enclosure-form.js.map +1 -1
- package/dist/content/excerpt.d.ts +1 -0
- package/dist/content/excerpt.d.ts.map +1 -1
- package/dist/content/excerpt.js +3 -0
- package/dist/content/excerpt.js.map +1 -1
- package/dist/content/index.d.ts +3 -3
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/index.js +2 -2
- package/dist/content/index.js.map +1 -1
- package/dist/content/kept-properties.d.ts +0 -1
- package/dist/content/kept-properties.d.ts.map +1 -1
- package/dist/content/kept-properties.js +2 -2
- package/dist/content/kept-properties.js.map +1 -1
- package/dist/content/locations.d.ts +0 -1
- package/dist/content/locations.d.ts.map +1 -1
- package/dist/content/locations.js +2 -2
- package/dist/content/locations.js.map +1 -1
- package/dist/content/media.d.ts +7 -0
- package/dist/content/media.d.ts.map +1 -1
- package/dist/content/media.js +12 -1
- package/dist/content/media.js.map +1 -1
- package/dist/content/metadata/strip-job.d.ts +16 -0
- package/dist/content/metadata/strip-job.d.ts.map +1 -0
- package/dist/content/metadata/strip-job.js +24 -0
- package/dist/content/metadata/strip-job.js.map +1 -0
- package/dist/content/metadata/sweep.d.ts +13 -1
- package/dist/content/metadata/sweep.d.ts.map +1 -1
- package/dist/content/metadata/sweep.js +47 -25
- package/dist/content/metadata/sweep.js.map +1 -1
- package/dist/content/permalink-file.d.ts +2 -1
- package/dist/content/permalink-file.d.ts.map +1 -1
- package/dist/content/permalink-file.js +3 -3
- package/dist/content/permalink-file.js.map +1 -1
- package/dist/content/photo-form.d.ts +1 -0
- package/dist/content/photo-form.d.ts.map +1 -1
- package/dist/content/photo-form.js +8 -5
- package/dist/content/photo-form.js.map +1 -1
- package/dist/content/photo.d.ts +1 -0
- 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.map +1 -1
- package/dist/content/post-fields.js +5 -9
- package/dist/content/post-fields.js.map +1 -1
- package/dist/content/read-form.d.ts +10 -3
- package/dist/content/read-form.d.ts.map +1 -1
- package/dist/content/read-form.js +67 -9
- package/dist/content/read-form.js.map +1 -1
- package/dist/content/read.d.ts +9 -2
- package/dist/content/read.d.ts.map +1 -1
- package/dist/content/read.js +22 -3
- package/dist/content/read.js.map +1 -1
- package/dist/content/store.d.ts +0 -1
- package/dist/content/store.d.ts.map +1 -1
- package/dist/content/store.js +0 -1
- package/dist/content/store.js.map +1 -1
- package/dist/content/uploads.d.ts +1 -1
- package/dist/content/uploads.d.ts.map +1 -1
- package/dist/content/uploads.js +6 -1
- package/dist/content/uploads.js.map +1 -1
- package/dist/content/write.d.ts +1 -1
- package/dist/content/write.d.ts.map +1 -1
- package/dist/content/write.js +7 -3
- package/dist/content/write.js.map +1 -1
- package/dist/dev-mode.d.ts +4 -26
- package/dist/dev-mode.d.ts.map +1 -1
- package/dist/dev-mode.js +4 -53
- package/dist/dev-mode.js.map +1 -1
- package/dist/export/export-archives.d.ts +29 -0
- package/dist/export/export-archives.d.ts.map +1 -0
- package/dist/export/export-archives.js +88 -0
- package/dist/export/export-archives.js.map +1 -0
- package/dist/export/export-job.d.ts +21 -0
- package/dist/export/export-job.d.ts.map +1 -0
- package/dist/export/export-job.js +63 -0
- package/dist/export/export-job.js.map +1 -0
- package/dist/export/site-export.d.ts +101 -0
- package/dist/export/site-export.d.ts.map +1 -0
- package/dist/export/site-export.js +243 -0
- package/dist/export/site-export.js.map +1 -0
- package/dist/export/site-import.d.ts +75 -0
- package/dist/export/site-import.d.ts.map +1 -0
- package/dist/export/site-import.js +492 -0
- package/dist/export/site-import.js.map +1 -0
- package/dist/exports.d.ts +9 -4
- package/dist/exports.d.ts.map +1 -1
- package/dist/exports.js +3 -1
- package/dist/exports.js.map +1 -1
- package/dist/federation/article.d.ts.map +1 -1
- package/dist/federation/article.js +22 -20
- package/dist/federation/article.js.map +1 -1
- package/dist/federation/backfill.d.ts +3 -1
- package/dist/federation/backfill.d.ts.map +1 -1
- package/dist/federation/backfill.js +5 -3
- package/dist/federation/backfill.js.map +1 -1
- package/dist/federation/cited-post.d.ts +1 -1
- package/dist/federation/cited-post.d.ts.map +1 -1
- package/dist/federation/cited-post.js +1 -1
- package/dist/federation/cited-post.js.map +1 -1
- package/dist/federation/delivery.d.ts +5 -2
- package/dist/federation/delivery.d.ts.map +1 -1
- package/dist/federation/delivery.js +16 -12
- package/dist/federation/delivery.js.map +1 -1
- package/dist/federation/federation.d.ts +7 -7
- package/dist/federation/federation.d.ts.map +1 -1
- package/dist/federation/federation.js +5 -12
- package/dist/federation/federation.js.map +1 -1
- package/dist/federation/handles.d.ts +1 -1
- package/dist/federation/handles.d.ts.map +1 -1
- package/dist/federation/handles.js +1 -1
- package/dist/federation/handles.js.map +1 -1
- package/dist/federation/inbox.js +1 -1
- package/dist/federation/inbox.js.map +1 -1
- package/dist/federation/keys.js +3 -3
- package/dist/federation/keys.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 +1 -1
- package/dist/federation/profiles.js.map +1 -1
- package/dist/federation/queue.d.ts +32 -17
- package/dist/federation/queue.d.ts.map +1 -1
- package/dist/federation/queue.js +173 -39
- package/dist/federation/queue.js.map +1 -1
- package/dist/federation/relays.d.ts +6 -2
- package/dist/federation/relays.d.ts.map +1 -1
- package/dist/federation/relays.js +43 -36
- package/dist/federation/relays.js.map +1 -1
- package/dist/federation/resend-job.d.ts +44 -0
- package/dist/federation/resend-job.d.ts.map +1 -0
- package/dist/federation/resend-job.js +59 -0
- package/dist/federation/resend-job.js.map +1 -0
- package/dist/files/atomic.d.ts +9 -0
- package/dist/files/atomic.d.ts.map +1 -1
- package/dist/files/atomic.js +1 -1
- package/dist/files/atomic.js.map +1 -1
- package/dist/files/data-files.d.ts +104 -0
- package/dist/files/data-files.d.ts.map +1 -0
- package/dist/files/data-files.js +330 -0
- package/dist/files/data-files.js.map +1 -0
- package/dist/files/export-archives.d.ts +12 -0
- package/dist/files/export-archives.d.ts.map +1 -0
- package/dist/files/export-archives.js +67 -0
- package/dist/files/export-archives.js.map +1 -0
- package/dist/files/static-files.d.ts.map +1 -1
- package/dist/files/static-files.js +7 -22
- package/dist/files/static-files.js.map +1 -1
- package/dist/files/tar.d.ts +29 -0
- package/dist/files/tar.d.ts.map +1 -0
- package/dist/files/tar.js +206 -0
- package/dist/files/tar.js.map +1 -0
- package/dist/files/upload-types.d.ts +81 -0
- package/dist/files/upload-types.d.ts.map +1 -0
- package/dist/files/upload-types.js +234 -0
- package/dist/files/upload-types.js.map +1 -0
- package/dist/forms/protection.d.ts +0 -8
- package/dist/forms/protection.d.ts.map +1 -1
- package/dist/forms/protection.js +2 -10
- package/dist/forms/protection.js.map +1 -1
- package/dist/images/icons.d.ts.map +1 -1
- package/dist/images/icons.js +2 -0
- package/dist/images/icons.js.map +1 -1
- package/dist/images/index.d.ts +1 -1
- package/dist/images/index.d.ts.map +1 -1
- package/dist/images/index.js +1 -1
- package/dist/images/index.js.map +1 -1
- package/dist/images/markup.d.ts +4 -1
- package/dist/images/markup.d.ts.map +1 -1
- package/dist/images/markup.js +10 -6
- package/dist/images/markup.js.map +1 -1
- package/dist/images/paths.d.ts +1 -4
- package/dist/images/paths.d.ts.map +1 -1
- package/dist/images/paths.js +6 -12
- package/dist/images/paths.js.map +1 -1
- package/dist/images/variants.d.ts +4 -2
- package/dist/images/variants.d.ts.map +1 -1
- package/dist/images/variants.js +21 -21
- package/dist/images/variants.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/indexnow.d.ts +4 -2
- package/dist/indexnow.d.ts.map +1 -1
- package/dist/indexnow.js +32 -20
- package/dist/indexnow.js.map +1 -1
- package/dist/indieauth/tokens.d.ts +0 -2
- package/dist/indieauth/tokens.d.ts.map +1 -1
- package/dist/indieauth/tokens.js +2 -4
- package/dist/indieauth/tokens.js.map +1 -1
- package/dist/jobs/file-records.d.ts +13 -0
- package/dist/jobs/file-records.d.ts.map +1 -0
- package/dist/jobs/file-records.js +104 -0
- package/dist/jobs/file-records.js.map +1 -0
- package/dist/jobs/in-process.d.ts +10 -0
- package/dist/jobs/in-process.d.ts.map +1 -0
- package/dist/jobs/in-process.js +45 -0
- package/dist/jobs/in-process.js.map +1 -0
- package/dist/jobs/lock-file.d.ts +13 -0
- package/dist/jobs/lock-file.d.ts.map +1 -0
- package/dist/jobs/lock-file.js +107 -0
- package/dist/jobs/lock-file.js.map +1 -0
- package/dist/jobs/processes.d.ts +11 -0
- package/dist/jobs/processes.d.ts.map +1 -0
- package/dist/jobs/processes.js +50 -0
- package/dist/jobs/processes.js.map +1 -0
- package/dist/jobs/queue.d.ts +18 -0
- package/dist/jobs/queue.d.ts.map +1 -0
- package/dist/jobs/queue.js +220 -0
- package/dist/jobs/queue.js.map +1 -0
- package/dist/jobs/types.d.ts +159 -0
- package/dist/jobs/types.d.ts.map +1 -0
- package/dist/jobs/types.js +22 -0
- package/dist/jobs/types.js.map +1 -0
- package/dist/mail/index.d.ts +0 -2
- package/dist/mail/index.d.ts.map +1 -1
- package/dist/mail/index.js +0 -1
- package/dist/mail/index.js.map +1 -1
- package/dist/maintenance.d.ts +5 -42
- package/dist/maintenance.d.ts.map +1 -1
- package/dist/maintenance.js +4 -67
- package/dist/maintenance.js.map +1 -1
- package/dist/media/library.d.ts +1 -1
- package/dist/media/library.d.ts.map +1 -1
- package/dist/media/library.js +4 -1
- package/dist/media/library.js.map +1 -1
- package/dist/media/uploads.d.ts +1 -1
- package/dist/media/uploads.d.ts.map +1 -1
- package/dist/media/uploads.js +1 -1
- package/dist/media/uploads.js.map +1 -1
- package/dist/micropub/endpoint.js +10 -10
- package/dist/micropub/endpoint.js.map +1 -1
- package/dist/micropub/media.d.ts +0 -2
- package/dist/micropub/media.d.ts.map +1 -1
- package/dist/micropub/media.js +5 -7
- package/dist/micropub/media.js.map +1 -1
- package/dist/notifications/comments.d.ts +4 -2
- package/dist/notifications/comments.d.ts.map +1 -1
- package/dist/notifications/comments.js +77 -65
- package/dist/notifications/comments.js.map +1 -1
- package/dist/notifications/digest.d.ts +2 -4
- package/dist/notifications/digest.d.ts.map +1 -1
- package/dist/notifications/digest.js +9 -10
- package/dist/notifications/digest.js.map +1 -1
- package/dist/notifications/index.d.ts +3 -3
- package/dist/notifications/index.d.ts.map +1 -1
- package/dist/notifications/index.js +3 -3
- package/dist/notifications/index.js.map +1 -1
- package/dist/notifications/mail-service.d.ts +10 -8
- package/dist/notifications/mail-service.d.ts.map +1 -1
- package/dist/notifications/mail-service.js +70 -70
- package/dist/notifications/mail-service.js.map +1 -1
- package/dist/notifications/optouts.d.ts +0 -2
- package/dist/notifications/optouts.d.ts.map +1 -1
- package/dist/notifications/optouts.js +2 -4
- package/dist/notifications/optouts.js.map +1 -1
- package/dist/notifications/tokens.d.ts +0 -2
- package/dist/notifications/tokens.d.ts.map +1 -1
- package/dist/notifications/tokens.js +2 -28
- package/dist/notifications/tokens.js.map +1 -1
- package/dist/notify.d.ts +4 -2
- package/dist/notify.d.ts.map +1 -1
- package/dist/notify.js +27 -15
- package/dist/notify.js.map +1 -1
- package/dist/plugin.d.ts +36 -16
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +1 -1
- package/dist/plugin.js.map +1 -1
- package/dist/plugins/changes.d.ts +0 -1
- package/dist/plugins/changes.d.ts.map +1 -1
- package/dist/plugins/changes.js +2 -3
- package/dist/plugins/changes.js.map +1 -1
- package/dist/plugins/data.d.ts +19 -0
- package/dist/plugins/data.d.ts.map +1 -0
- package/dist/plugins/data.js +117 -0
- package/dist/plugins/data.js.map +1 -0
- package/dist/plugins/enabled.d.ts +1 -13
- package/dist/plugins/enabled.d.ts.map +1 -1
- package/dist/plugins/enabled.js +11 -23
- package/dist/plugins/enabled.js.map +1 -1
- package/dist/plugins/install.d.ts +1 -1
- package/dist/plugins/install.d.ts.map +1 -1
- package/dist/plugins/install.js +7 -42
- package/dist/plugins/install.js.map +1 -1
- package/dist/plugins/migrate-settings.d.ts +7 -0
- package/dist/plugins/migrate-settings.d.ts.map +1 -0
- package/dist/plugins/migrate-settings.js +41 -0
- package/dist/plugins/migrate-settings.js.map +1 -0
- package/dist/plugins/registry.d.ts +10 -14
- package/dist/plugins/registry.d.ts.map +1 -1
- package/dist/plugins/registry.js +56 -36
- package/dist/plugins/registry.js.map +1 -1
- package/dist/plugins/settings.d.ts +5 -57
- package/dist/plugins/settings.d.ts.map +1 -1
- package/dist/plugins/settings.js +47 -180
- package/dist/plugins/settings.js.map +1 -1
- package/dist/plugins/site.d.ts +2 -1
- package/dist/plugins/site.d.ts.map +1 -1
- package/dist/plugins/site.js +5 -5
- package/dist/plugins/site.js.map +1 -1
- package/dist/privacy/retention.d.ts +4 -0
- package/dist/privacy/retention.d.ts.map +1 -1
- package/dist/privacy/retention.js +12 -5
- package/dist/privacy/retention.js.map +1 -1
- package/dist/settings/akismet.d.ts +9 -0
- package/dist/settings/akismet.d.ts.map +1 -0
- package/dist/settings/akismet.js +46 -0
- package/dist/settings/akismet.js.map +1 -0
- package/dist/settings/declare.d.ts +15 -0
- package/dist/settings/declare.d.ts.map +1 -0
- package/dist/settings/declare.js +20 -0
- package/dist/settings/declare.js.map +1 -0
- package/dist/settings/dev-mode.d.ts +29 -0
- package/dist/settings/dev-mode.d.ts.map +1 -0
- package/dist/settings/dev-mode.js +77 -0
- package/dist/settings/dev-mode.js.map +1 -0
- package/dist/settings/kinds.d.ts +13 -0
- package/dist/settings/kinds.d.ts.map +1 -0
- package/dist/settings/kinds.js +108 -0
- package/dist/settings/kinds.js.map +1 -0
- package/dist/settings/mail.d.ts +10 -0
- package/dist/settings/mail.d.ts.map +1 -0
- package/dist/settings/mail.js +92 -0
- package/dist/settings/mail.js.map +1 -0
- package/dist/settings/maintenance.d.ts +6 -0
- package/dist/settings/maintenance.d.ts.map +1 -0
- package/dist/settings/maintenance.js +33 -0
- package/dist/settings/maintenance.js.map +1 -0
- package/dist/settings/names.d.ts +7 -0
- package/dist/settings/names.d.ts.map +1 -0
- package/dist/settings/names.js +31 -0
- package/dist/settings/names.js.map +1 -0
- package/dist/settings/presence.d.ts +2 -0
- package/dist/settings/presence.d.ts.map +1 -0
- package/dist/settings/presence.js +7 -0
- package/dist/settings/presence.js.map +1 -0
- package/dist/settings/registry.d.ts +14 -0
- package/dist/settings/registry.d.ts.map +1 -0
- package/dist/settings/registry.js +369 -0
- package/dist/settings/registry.js.map +1 -0
- package/dist/settings/types.d.ts +176 -0
- package/dist/settings/types.d.ts.map +1 -0
- package/dist/settings/types.js +2 -0
- package/dist/settings/types.js.map +1 -0
- package/dist/site/namespace.d.ts +88 -0
- package/dist/site/namespace.d.ts.map +1 -0
- package/dist/site/namespace.js +471 -0
- package/dist/site/namespace.js.map +1 -0
- package/dist/site/setting-rows.d.ts +9 -10
- package/dist/site/setting-rows.d.ts.map +1 -1
- package/dist/site/setting-rows.js +109 -228
- package/dist/site/setting-rows.js.map +1 -1
- package/dist/site/settings-form.d.ts.map +1 -1
- package/dist/site/settings-form.js +6 -10
- package/dist/site/settings-form.js.map +1 -1
- package/dist/site/settings.d.ts +6 -322
- package/dist/site/settings.d.ts.map +1 -1
- package/dist/site/settings.js +13 -76
- package/dist/site/settings.js.map +1 -1
- package/dist/site/site-json.d.ts +0 -31
- package/dist/site/site-json.d.ts.map +1 -1
- package/dist/site/site-json.js +5 -49
- package/dist/site/site-json.js.map +1 -1
- package/dist/site/users.d.ts +0 -9
- package/dist/site/users.d.ts.map +1 -1
- package/dist/site/users.js +2 -11
- package/dist/site/users.js.map +1 -1
- package/dist/store/queue-database.d.ts +11 -0
- package/dist/store/queue-database.d.ts.map +1 -0
- package/dist/store/queue-database.js +39 -0
- package/dist/store/queue-database.js.map +1 -0
- package/dist/supervisor/control.d.ts +1 -0
- package/dist/supervisor/control.d.ts.map +1 -1
- package/dist/supervisor/control.js +10 -0
- package/dist/supervisor/control.js.map +1 -1
- package/dist/supervisor/primary.d.ts.map +1 -1
- package/dist/supervisor/primary.js +15 -3
- package/dist/supervisor/primary.js.map +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +1 -1
- package/dist/testing.js.map +1 -1
- package/dist/theme/site-data.d.ts +1 -1
- package/dist/theme/site-data.d.ts.map +1 -1
- package/dist/theme/site-data.js.map +1 -1
- package/dist/web/asset-routes.d.ts +6 -2
- package/dist/web/asset-routes.d.ts.map +1 -1
- package/dist/web/asset-routes.js +12 -4
- package/dist/web/asset-routes.js.map +1 -1
- package/dist/web/comment-routes.d.ts.map +1 -1
- package/dist/web/comment-routes.js +4 -4
- package/dist/web/comment-routes.js.map +1 -1
- package/dist/web/contact-routes.js +1 -1
- package/dist/web/contact-routes.js.map +1 -1
- package/dist/web/context.d.ts +5 -0
- package/dist/web/context.d.ts.map +1 -1
- package/dist/web/context.js +9 -4
- package/dist/web/context.js.map +1 -1
- package/dist/web/conversation.d.ts +1 -1
- package/dist/web/conversation.d.ts.map +1 -1
- package/dist/web/conversation.js +13 -16
- package/dist/web/conversation.js.map +1 -1
- package/dist/web/document-page.d.ts.map +1 -1
- package/dist/web/document-page.js +5 -4
- package/dist/web/document-page.js.map +1 -1
- package/dist/web/document-site.d.ts +1 -1
- package/dist/web/document-site.d.ts.map +1 -1
- package/dist/web/document-site.js +2 -1
- package/dist/web/document-site.js.map +1 -1
- package/dist/web/embed.js +1 -1
- package/dist/web/embed.js.map +1 -1
- package/dist/web/env.d.ts +9 -0
- package/dist/web/env.d.ts.map +1 -1
- package/dist/web/federation-routes.d.ts.map +1 -1
- package/dist/web/federation-routes.js +3 -1
- package/dist/web/federation-routes.js.map +1 -1
- package/dist/web/feed-item.js +1 -1
- package/dist/web/feed-item.js.map +1 -1
- package/dist/web/feed-routes.d.ts +3 -4
- package/dist/web/feed-routes.d.ts.map +1 -1
- package/dist/web/feed-routes.js +17 -15
- package/dist/web/feed-routes.js.map +1 -1
- package/dist/web/health.js +1 -1
- package/dist/web/health.js.map +1 -1
- package/dist/web/index.d.ts +1 -1
- package/dist/web/index.d.ts.map +1 -1
- package/dist/web/index.js.map +1 -1
- package/dist/web/indieauth-activity-log.d.ts +0 -2
- package/dist/web/indieauth-activity-log.d.ts.map +1 -1
- package/dist/web/indieauth-activity-log.js +2 -4
- package/dist/web/indieauth-activity-log.js.map +1 -1
- package/dist/web/indieauth-bearer.js +2 -2
- package/dist/web/indieauth-bearer.js.map +1 -1
- package/dist/web/indieauth-discovery.d.ts +0 -4
- package/dist/web/indieauth-discovery.d.ts.map +1 -1
- package/dist/web/indieauth-discovery.js +3 -10
- package/dist/web/indieauth-discovery.js.map +1 -1
- package/dist/web/indieauth-token.d.ts.map +1 -1
- package/dist/web/indieauth-token.js +3 -3
- package/dist/web/indieauth-token.js.map +1 -1
- package/dist/web/listing-pages.d.ts.map +1 -1
- package/dist/web/listing-pages.js +1 -2
- package/dist/web/listing-pages.js.map +1 -1
- package/dist/web/maintenance.js +3 -3
- package/dist/web/maintenance.js.map +1 -1
- package/dist/web/page-sources.d.ts +1 -2
- package/dist/web/page-sources.d.ts.map +1 -1
- package/dist/web/page-sources.js +6 -7
- package/dist/web/page-sources.js.map +1 -1
- package/dist/web/paths.js +1 -1
- package/dist/web/paths.js.map +1 -1
- package/dist/web/pingback-routes.d.ts.map +1 -1
- package/dist/web/pingback-routes.js +3 -3
- package/dist/web/pingback-routes.js.map +1 -1
- package/dist/web/plugin-federation.js +50 -40
- package/dist/web/plugin-federation.js.map +1 -1
- package/dist/web/render.d.ts +12 -5
- package/dist/web/render.d.ts.map +1 -1
- package/dist/web/render.js +31 -21
- package/dist/web/render.js.map +1 -1
- package/dist/web/request.js +1 -1
- package/dist/web/request.js.map +1 -1
- package/dist/web/routes.d.ts.map +1 -1
- package/dist/web/routes.js +8 -9
- package/dist/web/routes.js.map +1 -1
- package/dist/web/site-index.d.ts.map +1 -1
- package/dist/web/site-index.js +1 -2
- package/dist/web/site-index.js.map +1 -1
- package/dist/web/site-view.d.ts +0 -2
- package/dist/web/site-view.d.ts.map +1 -1
- package/dist/web/site-view.js +0 -2
- package/dist/web/site-view.js.map +1 -1
- package/dist/web/webmention-routes.d.ts.map +1 -1
- package/dist/web/webmention-routes.js +2 -2
- package/dist/web/webmention-routes.js.map +1 -1
- package/dist/web/well-known.d.ts.map +1 -1
- package/dist/web/well-known.js +6 -7
- package/dist/web/well-known.js.map +1 -1
- package/dist/webmention/cited-picture.js +1 -1
- package/dist/webmention/cited-picture.js.map +1 -1
- package/dist/webmention/pingback.d.ts +1 -8
- package/dist/webmention/pingback.d.ts.map +1 -1
- package/dist/webmention/pingback.js +2 -11
- package/dist/webmention/pingback.js.map +1 -1
- package/dist/webmention/receive.d.ts +3 -1
- package/dist/webmention/receive.d.ts.map +1 -1
- package/dist/webmention/receive.js +5 -3
- package/dist/webmention/receive.js.map +1 -1
- package/dist/webmention/reply-contexts.d.ts +14 -3
- package/dist/webmention/reply-contexts.d.ts.map +1 -1
- package/dist/webmention/reply-contexts.js +12 -10
- package/dist/webmention/reply-contexts.js.map +1 -1
- package/dist/webmention/service.d.ts +3 -1
- package/dist/webmention/service.d.ts.map +1 -1
- package/dist/webmention/service.js +66 -53
- package/dist/webmention/service.js.map +1 -1
- package/package.json +13 -11
- package/themes/default/partials/post-list.njk +11 -11
- package/themes/default/src/style.css +12 -0
- package/themes/default/static/style.css +19 -0
package/dist/cli.js
CHANGED
|
@@ -10,22 +10,32 @@ import { credentialProblem, emailProblem } from './admin/credentials.js';
|
|
|
10
10
|
import { migrateUsersToFile } from './admin/legacy-migrations.js';
|
|
11
11
|
import { adminStoreOwning, openAdminDatabase } from './store/admin-store.js';
|
|
12
12
|
import { databaseFile, discardDatabase } from './cache.js';
|
|
13
|
-
import {
|
|
13
|
+
import { CONTENT_SCRATCH_FILES, dataPath } from './files/data-files.js';
|
|
14
|
+
import { compactTime, exportFileName, planSiteExport, writeSiteExport, } from './export/site-export.js';
|
|
15
|
+
import { checkImportTargets, discardStaging, finishSiteImport, importNotes, installArchivedPlugins, placeSiteImport, pluginFailureLine, readSiteManifest, restoreEnabledPlugins, stageSiteImport, } from './export/site-import.js';
|
|
16
|
+
import { CONFIG_FILENAMES, loadConfig, loadResolvedConfig } from './config-loader.js';
|
|
17
|
+
import { resolveConfig } from './config.js';
|
|
14
18
|
import { migrateCommentEmails, migrateCommentKeys } from './comments/migrations.js';
|
|
15
|
-
import {
|
|
19
|
+
import { STRIP_METADATA_JOB } from './content/metadata/strip-job.js';
|
|
20
|
+
import { RESEND_JOB } from './federation/resend-job.js';
|
|
16
21
|
import { createUser, DuplicateUsernameError } from './site/users.js';
|
|
17
|
-
import {
|
|
18
|
-
import { createCms } from './index.js';
|
|
22
|
+
import { createCms, settleConfig } from './index.js';
|
|
19
23
|
import { initSite, ownManifest, seedStarterContent } from './init.js';
|
|
24
|
+
import { finishedResult } from './jobs/types.js';
|
|
20
25
|
import { importPluginFolders, scanPluginFolders } from './plugins/folder.js';
|
|
21
26
|
import { ADD_WITH_COMMAND, addPlugin, installedFolders, parsePackageSpec, pluginRegistry, removePlugin, requirementNotes, } from './plugins/install.js';
|
|
22
27
|
import { describeUpgrade, upgradePlugins } from './plugins/upgrade.js';
|
|
28
|
+
import { migratePluginSettings } from './plugins/migrate-settings.js';
|
|
29
|
+
import { siteDataFiles } from './plugins/data.js';
|
|
30
|
+
import { readEnabledPlugins } from './plugins/enabled.js';
|
|
23
31
|
import { pluginSite, sitePluginRegistry } from './plugins/site.js';
|
|
24
|
-
import { askToReload } from './supervisor/control.js';
|
|
32
|
+
import { askToReload, isServing } from './supervisor/control.js';
|
|
25
33
|
import { superviseCluster } from './supervisor/primary.js';
|
|
26
34
|
import { processChannel, superviseWorker } from './supervisor/worker.js';
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
35
|
+
import { DEV_MODE, DEV_MODE_LATCHED } from './settings/dev-mode.js';
|
|
36
|
+
import { MAINTENANCE, MAINTENANCE_FILE } from './settings/maintenance.js';
|
|
37
|
+
import { overridden, sourceLabel } from './settings/registry.js';
|
|
38
|
+
import { createSettings } from './site/namespace.js';
|
|
29
39
|
import { messageOf } from './util/errors.js';
|
|
30
40
|
const COMMANDS = {
|
|
31
41
|
serve: {
|
|
@@ -106,6 +116,45 @@ const COMMANDS = {
|
|
|
106
116
|
],
|
|
107
117
|
run: devModeCommand,
|
|
108
118
|
},
|
|
119
|
+
settings: {
|
|
120
|
+
synopsis: [
|
|
121
|
+
'settings list [<namespace>] [--config <file>]',
|
|
122
|
+
'settings get <namespace.key> [--config <file>]',
|
|
123
|
+
'settings set <namespace.key> (<value> | --unset) [--config <file>]',
|
|
124
|
+
'settings migrate-plugins [--config <file>]',
|
|
125
|
+
],
|
|
126
|
+
help: [
|
|
127
|
+
[
|
|
128
|
+
'settings list',
|
|
129
|
+
[
|
|
130
|
+
'Print every runtime setting: its value in effect, where',
|
|
131
|
+
'that value came from (env, config, file or default) and',
|
|
132
|
+
'what it does. A secret prints as (set) or (not set).',
|
|
133
|
+
"Each running plugin's settings follow the core ones, as",
|
|
134
|
+
'@geekity/plugin-llm.default_model.',
|
|
135
|
+
],
|
|
136
|
+
],
|
|
137
|
+
['settings get', ['Print one value in effect, and what overrides it, if', 'anything.']],
|
|
138
|
+
[
|
|
139
|
+
'settings set',
|
|
140
|
+
[
|
|
141
|
+
'Store one value, or remove it with --unset so the default',
|
|
142
|
+
'applies. A setting the environment or the config overrides',
|
|
143
|
+
'is refused. A secret set here is left in the shell history.',
|
|
144
|
+
],
|
|
145
|
+
],
|
|
146
|
+
[
|
|
147
|
+
'settings migrate-plugins',
|
|
148
|
+
[
|
|
149
|
+
"Move each plugin's settings out of content/_data/site.json",
|
|
150
|
+
'into data/plugins/<name>/settings.json, keeping enabled',
|
|
151
|
+
'where it is. A server does this when it starts; run it',
|
|
152
|
+
'with the site stopped to do it first. Safe to run twice.',
|
|
153
|
+
],
|
|
154
|
+
],
|
|
155
|
+
],
|
|
156
|
+
run: settingsCommand,
|
|
157
|
+
},
|
|
109
158
|
'strip-metadata': {
|
|
110
159
|
synopsis: ['strip-metadata [--config <file>]'],
|
|
111
160
|
help: [
|
|
@@ -122,6 +171,45 @@ const COMMANDS = {
|
|
|
122
171
|
],
|
|
123
172
|
run: stripMetadataCommand,
|
|
124
173
|
},
|
|
174
|
+
export: {
|
|
175
|
+
synopsis: [
|
|
176
|
+
'export [--out <file>] [--with-credentials] [--without-content] [--list] [--config <file>]',
|
|
177
|
+
],
|
|
178
|
+
help: [
|
|
179
|
+
[
|
|
180
|
+
'export',
|
|
181
|
+
[
|
|
182
|
+
'Write the site to a .tar.gz: content/ and every file in',
|
|
183
|
+
'data/ the site cannot rebuild, with manifest.json first.',
|
|
184
|
+
'Credentials are left out unless --with-credentials is given.',
|
|
185
|
+
'It only reads, so it runs while the site serves. It prints',
|
|
186
|
+
'the deliveries waiting in the queue, which are never',
|
|
187
|
+
'exported. --list prints what each file in data/ is and',
|
|
188
|
+
'writes nothing.',
|
|
189
|
+
],
|
|
190
|
+
],
|
|
191
|
+
],
|
|
192
|
+
run: exportCommand,
|
|
193
|
+
},
|
|
194
|
+
import: {
|
|
195
|
+
synopsis: ['import <file> [--replace] [--dev-mode] [--new-base-url] [--config <file>]'],
|
|
196
|
+
help: [
|
|
197
|
+
[
|
|
198
|
+
'import',
|
|
199
|
+
[
|
|
200
|
+
'Restore a site from an archive geekity export wrote, with the',
|
|
201
|
+
'site stopped. Every file is checked against the manifest and',
|
|
202
|
+
'unpacked beside content/ and data/ before it replaces them.',
|
|
203
|
+
'Folder plugins are installed from the npm registry at the',
|
|
204
|
+
'versions the archive records, and the database is rebuilt.',
|
|
205
|
+
'It exits 1 when a plugin could not be installed, naming it',
|
|
206
|
+
'and the command to retry.',
|
|
207
|
+
],
|
|
208
|
+
],
|
|
209
|
+
],
|
|
210
|
+
sharedWithPlugins: true,
|
|
211
|
+
run: importCommand,
|
|
212
|
+
},
|
|
125
213
|
user: {
|
|
126
214
|
synopsis: ['user add <username> [--password <pw>] [--email <address>] [--config <file>]'],
|
|
127
215
|
help: [
|
|
@@ -175,9 +263,19 @@ const COMMANDS = {
|
|
|
175
263
|
* The options one command reads out of {@link ParsedArgs.flags}, each of which
|
|
176
264
|
* carries a value.
|
|
177
265
|
*/
|
|
178
|
-
const VALUE_FLAGS = ['until'];
|
|
266
|
+
const VALUE_FLAGS = ['until', 'out'];
|
|
179
267
|
/** The options that are simply on or off. */
|
|
180
|
-
const SWITCH_FLAGS = [
|
|
268
|
+
const SWITCH_FLAGS = [
|
|
269
|
+
'all',
|
|
270
|
+
'check',
|
|
271
|
+
'unset',
|
|
272
|
+
'with-credentials',
|
|
273
|
+
'without-content',
|
|
274
|
+
'list',
|
|
275
|
+
'replace',
|
|
276
|
+
'dev-mode',
|
|
277
|
+
'new-base-url',
|
|
278
|
+
];
|
|
181
279
|
const OPTIONS_HELP = `Options:
|
|
182
280
|
--config <file> Config file to load. Defaults to the first of
|
|
183
281
|
${CONFIG_FILENAMES.join(', ')} found in the working directory.
|
|
@@ -191,8 +289,24 @@ const OPTIONS_HELP = `Options:
|
|
|
191
289
|
ISO 8601 time such as 2026-09-28T14:00:00Z. It is the
|
|
192
290
|
Retry-After a client is sent, and the maintenance page
|
|
193
291
|
says it.
|
|
292
|
+
--unset With settings set: remove the stored value.
|
|
194
293
|
--all With resend: every announced post rather than named ones.
|
|
195
294
|
--check With plugin upgrade: say what would change, install nothing.
|
|
295
|
+
--out <file> With export: the archive to write. Defaults to
|
|
296
|
+
geekity-<host>-<time>.tar.gz in the working directory.
|
|
297
|
+
--with-credentials
|
|
298
|
+
With export: include the API keys and logins kept in
|
|
299
|
+
data/ (mail.json, akismet.json, each plugin's secrets).
|
|
300
|
+
--without-content
|
|
301
|
+
With export: leave content/ out.
|
|
302
|
+
--list With export: print each file data/ may hold, its class
|
|
303
|
+
and what is lost without it, and write nothing.
|
|
304
|
+
--replace With import: move what content/ and data/ hold into
|
|
305
|
+
<dir>/.geekity-before-import-<time> when they hold a site.
|
|
306
|
+
--dev-mode With import: turn dev mode on, for a staging copy of a
|
|
307
|
+
live site.
|
|
308
|
+
--new-base-url With import: accept a base URL in effect that differs
|
|
309
|
+
from the one the archive was exported from.
|
|
196
310
|
-h, --help Show this help.
|
|
197
311
|
-v, --version Show the installed version.
|
|
198
312
|
|
|
@@ -314,9 +428,12 @@ function isCommand(value) {
|
|
|
314
428
|
}
|
|
315
429
|
/** Run one command. Resolves with the exit code the process should use. */
|
|
316
430
|
async function main(argv) {
|
|
317
|
-
const
|
|
318
|
-
|
|
319
|
-
|
|
431
|
+
const words = leadingWords(argv);
|
|
432
|
+
const first = words[0];
|
|
433
|
+
if (first !== undefined && !argv.some(isHelpOrVersion)) {
|
|
434
|
+
if (!isCommand(first) || (await pluginExtends(first, words, configFlag(argv)))) {
|
|
435
|
+
return await pluginCommand(argv);
|
|
436
|
+
}
|
|
320
437
|
}
|
|
321
438
|
const parsed = parseArgs(argv);
|
|
322
439
|
if (parsed.command === 'help') {
|
|
@@ -348,34 +465,33 @@ async function initCommand({ args }) {
|
|
|
348
465
|
].join('\n'));
|
|
349
466
|
return 0;
|
|
350
467
|
}
|
|
351
|
-
/**
|
|
352
|
-
* `geekity maintenance on|off|status` (TASK-130).
|
|
353
|
-
*
|
|
354
|
-
* Only the file under `data/` is touched, so this works the same with the
|
|
355
|
-
* site running or stopped: a running site re-reads it within a second.
|
|
356
|
-
*/
|
|
357
468
|
async function maintenanceCommand({ args, configPath, flags }) {
|
|
358
469
|
const action = args[0];
|
|
359
470
|
const config = await loadResolvedConfig(configPath);
|
|
360
|
-
const
|
|
471
|
+
const settings = createSettings({ config });
|
|
361
472
|
if (action === 'on') {
|
|
362
473
|
const until = untilFlag(text(flags, 'until'));
|
|
363
|
-
await
|
|
474
|
+
await setOrThrow(settings, 'maintenance', { on: true, until: until?.toISOString() ?? '' });
|
|
475
|
+
const file = dataPath(config.dataDir, MAINTENANCE_FILE);
|
|
364
476
|
process.stdout.write(`Maintenance mode is on (${file}).${untilLine(until)}\n`);
|
|
365
477
|
return 0;
|
|
366
478
|
}
|
|
367
479
|
if (action === 'off') {
|
|
368
|
-
await
|
|
369
|
-
|
|
480
|
+
if (overridden((await settings.resolve(MAINTENANCE.on)).source)) {
|
|
481
|
+
throw new Error(`Maintenance mode is still on.${forcedLine(true)}`);
|
|
482
|
+
}
|
|
483
|
+
await setOrThrow(settings, 'maintenance', { on: false });
|
|
484
|
+
process.stdout.write('Maintenance mode is off.\n');
|
|
370
485
|
return 0;
|
|
371
486
|
}
|
|
372
487
|
if (action === 'status') {
|
|
373
|
-
const
|
|
374
|
-
if (
|
|
488
|
+
const on = await settings.resolve(MAINTENANCE.on);
|
|
489
|
+
if (!on.value) {
|
|
375
490
|
process.stdout.write('Maintenance mode is off.\n');
|
|
376
491
|
}
|
|
377
492
|
else {
|
|
378
|
-
|
|
493
|
+
const until = await settings.get(MAINTENANCE.until);
|
|
494
|
+
process.stdout.write(`Maintenance mode is on.${untilLine(until === '' ? undefined : new Date(until))}${forcedLine(overridden(on.source))}\n`);
|
|
379
495
|
}
|
|
380
496
|
return 0;
|
|
381
497
|
}
|
|
@@ -384,28 +500,170 @@ async function maintenanceCommand({ args, configPath, flags }) {
|
|
|
384
500
|
async function devModeCommand({ args, configPath }) {
|
|
385
501
|
const action = args[0];
|
|
386
502
|
const config = await loadResolvedConfig(configPath);
|
|
503
|
+
const settings = createSettings({ config });
|
|
387
504
|
if (action === 'on') {
|
|
388
|
-
|
|
505
|
+
await setOrThrow(settings, 'dev_mode', { on: true });
|
|
389
506
|
process.stdout.write('Dev mode is on: nothing the site does is sent until `geekity dev-mode off`.\n');
|
|
390
507
|
return 0;
|
|
391
508
|
}
|
|
392
509
|
if (action === 'off') {
|
|
393
510
|
if (config.devMode) {
|
|
394
|
-
throw new Error(
|
|
395
|
-
'Remove it, then run geekity dev-mode off again.');
|
|
511
|
+
throw new Error(`${DEV_MODE_LATCHED} Remove it, then run geekity dev-mode off again.`);
|
|
396
512
|
}
|
|
397
|
-
const wasOn =
|
|
513
|
+
const wasOn = await settings.get(DEV_MODE.on);
|
|
514
|
+
await setOrThrow(settings, 'dev_mode', { on: false });
|
|
398
515
|
process.stdout.write(wasOn
|
|
399
516
|
? 'Dev mode is off: the site is live. Nothing held while it was on will be sent.\n'
|
|
400
517
|
: 'Dev mode was already off: the site is live.\n');
|
|
401
518
|
return 0;
|
|
402
519
|
}
|
|
403
520
|
if (action === 'status') {
|
|
404
|
-
process.stdout.write(
|
|
521
|
+
process.stdout.write((await settings.get(DEV_MODE.on)) ? 'Dev mode is on.\n' : 'Dev mode is off.\n');
|
|
405
522
|
return 0;
|
|
406
523
|
}
|
|
407
524
|
throw new Error('geekity dev-mode needs on, off or status.');
|
|
408
525
|
}
|
|
526
|
+
async function settingsCommand({ args, configPath, flags }) {
|
|
527
|
+
const [action, name, value] = args;
|
|
528
|
+
const config = await loadResolvedConfig(configPath);
|
|
529
|
+
if (action === 'migrate-plugins' && name === undefined) {
|
|
530
|
+
const moved = migratePluginSettings({
|
|
531
|
+
contentDir: config.contentDir,
|
|
532
|
+
dataDir: config.dataDir,
|
|
533
|
+
log: (line) => process.stdout.write(`${line}\n`),
|
|
534
|
+
});
|
|
535
|
+
if (moved.length === 0) {
|
|
536
|
+
process.stdout.write('No plugin settings are left in content/_data/site.json.\n');
|
|
537
|
+
}
|
|
538
|
+
return 0;
|
|
539
|
+
}
|
|
540
|
+
const request = settingsRequest(action, name, value, flags['unset'] === true);
|
|
541
|
+
if (request === undefined) {
|
|
542
|
+
throw new Error('geekity settings needs list [<namespace>], get <namespace.key>, set <namespace.key> with a value or --unset, or migrate-plugins.');
|
|
543
|
+
}
|
|
544
|
+
const settings = await settingsWithRunningPlugins(config);
|
|
545
|
+
if (request.action === 'list') {
|
|
546
|
+
const refs = settings.list().filter((ref) => name === undefined || ref.namespace === name);
|
|
547
|
+
if (refs.length === 0)
|
|
548
|
+
throw new Error(`There is no settings namespace ${String(name)}.`);
|
|
549
|
+
const rows = await Promise.all(refs.map((ref) => settingRow(settings, ref)));
|
|
550
|
+
process.stdout.write(table(rows));
|
|
551
|
+
return 0;
|
|
552
|
+
}
|
|
553
|
+
const ref = settingNamed(settings, request.name);
|
|
554
|
+
if (request.action === 'get') {
|
|
555
|
+
const resolved = await settings.resolve(ref);
|
|
556
|
+
const lines = [shown(ref, resolved.value)];
|
|
557
|
+
if (overridden(resolved.source)) {
|
|
558
|
+
const held = resolved.stored === undefined ? 'nothing' : shown(ref, resolved.stored);
|
|
559
|
+
lines.push(`overridden by ${sourceLabel(resolved.source)}; the file holds ${held}`);
|
|
560
|
+
}
|
|
561
|
+
process.stdout.write(`${lines.join('\n')}\n`);
|
|
562
|
+
return 0;
|
|
563
|
+
}
|
|
564
|
+
const { type } = ref.declaration;
|
|
565
|
+
let stored;
|
|
566
|
+
if (request.value !== undefined) {
|
|
567
|
+
const parsed = type.fromText(request.value);
|
|
568
|
+
if (!parsed.ok)
|
|
569
|
+
throw new Error(`${request.name} ${parsed.problem}.`);
|
|
570
|
+
stored = type.toJson(parsed.value);
|
|
571
|
+
}
|
|
572
|
+
await setOrThrow(settings, ref.namespace, { [ref.key]: stored });
|
|
573
|
+
process.stdout.write(table([await settingRow(settings, ref)]));
|
|
574
|
+
return 0;
|
|
575
|
+
}
|
|
576
|
+
function settingsRequest(action, name, value, unset) {
|
|
577
|
+
if (action === 'list')
|
|
578
|
+
return { action };
|
|
579
|
+
if (name === undefined)
|
|
580
|
+
return undefined;
|
|
581
|
+
if (action === 'get')
|
|
582
|
+
return { action, name };
|
|
583
|
+
if (action === 'set' && (value !== undefined) !== unset)
|
|
584
|
+
return { action, name, value };
|
|
585
|
+
return undefined;
|
|
586
|
+
}
|
|
587
|
+
async function settingsWithRunningPlugins(config) {
|
|
588
|
+
migratePluginSettings({
|
|
589
|
+
contentDir: config.contentDir,
|
|
590
|
+
dataDir: config.dataDir,
|
|
591
|
+
log: (line) => process.stderr.write(`${line}\n`),
|
|
592
|
+
});
|
|
593
|
+
const settings = createSettings({ config });
|
|
594
|
+
let registry;
|
|
595
|
+
try {
|
|
596
|
+
registry = await loadSitePlugins(config, settings);
|
|
597
|
+
}
|
|
598
|
+
catch (error) {
|
|
599
|
+
process.stderr.write(`Plugin settings are not listed: ${messageOf(error)}\n`);
|
|
600
|
+
return settings;
|
|
601
|
+
}
|
|
602
|
+
const enabled = readEnabledPlugins(config.contentDir);
|
|
603
|
+
const running = registry.active(enabled);
|
|
604
|
+
for (const entry of registry.plugins) {
|
|
605
|
+
const { name } = entry.plugin;
|
|
606
|
+
const declared = entry.settingsNamespace !== undefined;
|
|
607
|
+
const unremarkable = !declared && !enabled.has(name) && entry.problem === undefined;
|
|
608
|
+
if (running.has(name) || unremarkable)
|
|
609
|
+
continue;
|
|
610
|
+
const unlisted = declared ? ' Its settings are not listed.' : '';
|
|
611
|
+
process.stderr.write(`${name} ${whyNotRunning(entry, enabled)}${unlisted}\n`);
|
|
612
|
+
if (declared)
|
|
613
|
+
settings.unregister(name);
|
|
614
|
+
}
|
|
615
|
+
return settings;
|
|
616
|
+
}
|
|
617
|
+
function whyNotRunning(entry, enabled) {
|
|
618
|
+
if (entry.problem !== undefined)
|
|
619
|
+
return `did not load: ${entry.problem}`;
|
|
620
|
+
if (enabled.has(entry.plugin.name)) {
|
|
621
|
+
return 'is enabled but not running, because a plugin it requires is not running.';
|
|
622
|
+
}
|
|
623
|
+
return 'is installed but not enabled.';
|
|
624
|
+
}
|
|
625
|
+
function settingNamed(settings, name) {
|
|
626
|
+
const dot = name.lastIndexOf('.');
|
|
627
|
+
const found = settings
|
|
628
|
+
.list()
|
|
629
|
+
.find((ref) => ref.namespace === name.slice(0, dot) && ref.key === name.slice(dot + 1));
|
|
630
|
+
if (found === undefined) {
|
|
631
|
+
throw new Error(`There is no setting ${name}. geekity settings list names them.`);
|
|
632
|
+
}
|
|
633
|
+
return found;
|
|
634
|
+
}
|
|
635
|
+
async function setOrThrow(settings, namespace, changes) {
|
|
636
|
+
const result = await settings.set(namespace, new Map(Object.entries(changes)), 'cli');
|
|
637
|
+
if (!result.ok)
|
|
638
|
+
throw new Error(Object.values(result.problems).join(' '));
|
|
639
|
+
}
|
|
640
|
+
function shown(ref, value) {
|
|
641
|
+
if (ref.declaration.secret === true) {
|
|
642
|
+
return value === ref.declaration.default ? '(not set)' : '(set)';
|
|
643
|
+
}
|
|
644
|
+
return ref.declaration.type.toText(value);
|
|
645
|
+
}
|
|
646
|
+
async function settingRow(settings, ref) {
|
|
647
|
+
const resolved = await settings.resolve(ref);
|
|
648
|
+
let source = sourceLabel(resolved.source);
|
|
649
|
+
if (overridden(resolved.source) && resolved.stored !== undefined) {
|
|
650
|
+
source += ` (file: ${shown(ref, resolved.stored)})`;
|
|
651
|
+
}
|
|
652
|
+
if (ref.declaration.env === false)
|
|
653
|
+
source += ', not overridable';
|
|
654
|
+
return [
|
|
655
|
+
`${ref.namespace}.${ref.key}`,
|
|
656
|
+
shown(ref, resolved.value),
|
|
657
|
+
source,
|
|
658
|
+
ref.declaration.description,
|
|
659
|
+
];
|
|
660
|
+
}
|
|
661
|
+
function table(rows) {
|
|
662
|
+
const widths = rows[0]?.map((_, column) => Math.max(...rows.map((row) => row[column]?.length ?? 0))) ?? [];
|
|
663
|
+
return rows
|
|
664
|
+
.map((row) => `${row.map((cell, column) => (column === row.length - 1 ? cell : cell.padEnd(widths[column] ?? 0))).join(' ')}\n`)
|
|
665
|
+
.join('');
|
|
666
|
+
}
|
|
409
667
|
function untilFlag(value) {
|
|
410
668
|
if (value === undefined)
|
|
411
669
|
return undefined;
|
|
@@ -423,28 +681,52 @@ function forcedLine(forced) {
|
|
|
423
681
|
? ' GEEKITY_MAINTENANCE or the maintenance setting keeps it on until the site restarts without it.'
|
|
424
682
|
: '';
|
|
425
683
|
}
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
process.stderr.write(
|
|
684
|
+
/**
|
|
685
|
+
* Run one job in this process and return its result, or say on standard
|
|
686
|
+
* error why there is none. A job of the same name that is already active
|
|
687
|
+
* stops it before it is queued. A queued job counts only while a server is up
|
|
688
|
+
* to run it: one a command left queued when it died runs when a server next
|
|
689
|
+
* starts, and is no reason to refuse while none is.
|
|
690
|
+
*/
|
|
691
|
+
async function runJobHere(config, job, payload, what, prepare) {
|
|
692
|
+
const cms = createCms(config);
|
|
693
|
+
let status;
|
|
694
|
+
try {
|
|
695
|
+
await prepare?.(cms);
|
|
696
|
+
const enqueued = await cms.jobs.enqueueUnlessActive(job, payload, {
|
|
697
|
+
countQueued: await isServing(config.dataDir),
|
|
698
|
+
});
|
|
699
|
+
if (!enqueued.queued) {
|
|
700
|
+
process.stderr.write(`A ${job.name} job is already ${enqueued.active.state}, so this one did not start. ` +
|
|
701
|
+
`Run the command again once it finishes.\n`);
|
|
702
|
+
return undefined;
|
|
443
703
|
}
|
|
704
|
+
status = await cms.jobs.run(enqueued.id);
|
|
444
705
|
}
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
706
|
+
finally {
|
|
707
|
+
await cms.close();
|
|
708
|
+
}
|
|
709
|
+
const result = finishedResult(job, status);
|
|
710
|
+
if (result === undefined) {
|
|
711
|
+
const problem = status.state === 'failed' ? status.error : `The job ended ${status.state}.`;
|
|
712
|
+
process.stderr.write(`The ${what} did not finish: ${problem}\n`);
|
|
713
|
+
}
|
|
714
|
+
return result;
|
|
715
|
+
}
|
|
716
|
+
async function stripMetadataCommand({ configPath }) {
|
|
717
|
+
const config = await loadResolvedConfig(configPath, (loaded) => ({ ...loaded, watch: false }));
|
|
718
|
+
const report = await runJobHere(config, STRIP_METADATA_JOB, null, 'sweep');
|
|
719
|
+
if (report === undefined)
|
|
720
|
+
return 1;
|
|
721
|
+
for (const file of report.stripped) {
|
|
722
|
+
process.stdout.write(`${file.path}: removed ${file.removed.join(', ')}\n`);
|
|
723
|
+
}
|
|
724
|
+
for (const file of report.unreadable) {
|
|
725
|
+
process.stderr.write(`${file.path}: ${file.problem} Left as it was.\n`);
|
|
726
|
+
}
|
|
727
|
+
process.stdout.write(`Checked ${count(report.checked, 'file')}: ${String(report.stripped.length)} stripped, ` +
|
|
728
|
+
`${String(report.clean)} already clean, ${String(report.unreadable.length)} unreadable\n`);
|
|
729
|
+
return report.unreadable.length === 0 ? 0 : 1;
|
|
448
730
|
}
|
|
449
731
|
/**
|
|
450
732
|
* `geekity sync`: bring the index into line with the files once and stop.
|
|
@@ -478,43 +760,39 @@ async function syncCommand({ configPath }) {
|
|
|
478
760
|
* Mastodon keeps the copy of a post it first fetched, so a property added
|
|
479
761
|
* later — the quote policy (TASK-125) is the one that made this a command —
|
|
480
762
|
* reaches a post already out only through an `Update`. This is the resend
|
|
481
|
-
* button on the federation screen, for every post at once
|
|
482
|
-
*
|
|
763
|
+
* button on the federation screen, for every post at once, and it runs the
|
|
764
|
+
* same resend job (TASK-393). Delivery runs with no queue, so each activity
|
|
765
|
+
* has been posted before the process exits.
|
|
483
766
|
*/
|
|
484
767
|
async function resendCommand({ args, configPath, flags }) {
|
|
485
768
|
const all = flags['all'] === true;
|
|
486
769
|
if (all === args.length > 0) {
|
|
487
770
|
throw new Error('geekity resend needs either --all or the slugs of the posts to resend, and not both.');
|
|
488
771
|
}
|
|
489
|
-
const
|
|
490
|
-
...
|
|
772
|
+
const config = await loadResolvedConfig(configPath, (loaded) => ({
|
|
773
|
+
...loaded,
|
|
491
774
|
watch: false,
|
|
492
|
-
federation: { ...
|
|
493
|
-
}))
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
process.stdout.write(`${slug}: ${report.activityType} to ${String(reached)} of ` +
|
|
511
|
-
`${String(report.deliveries.length)} inboxes\n`);
|
|
775
|
+
federation: { ...loaded.federation, queue: null },
|
|
776
|
+
}));
|
|
777
|
+
const report = await runJobHere(config, RESEND_JOB, { slugs: all ? 'all' : args, webmentions: false }, 'resend', (cms) => cms.sync());
|
|
778
|
+
if (report === undefined)
|
|
779
|
+
return 1;
|
|
780
|
+
let failed = 0;
|
|
781
|
+
for (const post of report.posts) {
|
|
782
|
+
const activity = post.resent ? post.activity : null;
|
|
783
|
+
if (activity === null) {
|
|
784
|
+
process.stderr.write(`${post.slug}: nothing to resend, no announced post has that slug.\n`);
|
|
785
|
+
failed += 1;
|
|
786
|
+
}
|
|
787
|
+
else if (activity.heldByDevMode) {
|
|
788
|
+
process.stdout.write(`${post.slug}: ${activity.activityType} held by dev mode, nothing sent\n`);
|
|
789
|
+
}
|
|
790
|
+
else {
|
|
791
|
+
process.stdout.write(`${post.slug}: ${activity.activityType} to ${String(activity.reached)} of ` +
|
|
792
|
+
`${String(activity.inboxes)} inboxes\n`);
|
|
512
793
|
}
|
|
513
|
-
return failed === 0 ? 0 : 1;
|
|
514
|
-
}
|
|
515
|
-
finally {
|
|
516
|
-
await cms.close();
|
|
517
794
|
}
|
|
795
|
+
return failed === 0 ? 0 : 1;
|
|
518
796
|
}
|
|
519
797
|
/**
|
|
520
798
|
* `geekity rebuild`: throw the database away and read it back out of the files.
|
|
@@ -544,11 +822,14 @@ async function rebuildCommand({ configPath }) {
|
|
|
544
822
|
'writing to a file nothing can find.\n');
|
|
545
823
|
return 1;
|
|
546
824
|
}
|
|
825
|
+
return (await rebuildDatabase(config)) > 0 ? 1 : 0;
|
|
826
|
+
}
|
|
827
|
+
async function rebuildDatabase(config) {
|
|
547
828
|
discardDatabase(config.dataDir);
|
|
548
829
|
const cms = createCms(config);
|
|
549
830
|
try {
|
|
550
831
|
const result = await cms.sync();
|
|
551
|
-
process.stdout.write(`Rebuilt ${
|
|
832
|
+
process.stdout.write(`Rebuilt ${databaseFile(config.dataDir)} from the files.\n` +
|
|
552
833
|
`Scanned ${String(result.scanned)}: ${String(result.created)} created, ` +
|
|
553
834
|
`${String(result.updated)} updated, ${String(result.removed)} removed, ` +
|
|
554
835
|
`${String(result.unchanged)} unchanged, ${String(result.failed)} failed\n` +
|
|
@@ -559,14 +840,130 @@ async function rebuildCommand({ configPath }) {
|
|
|
559
840
|
process.stderr.write(`${String(result.failed)} file${result.failed === 1 ? '' : 's'} could not be parsed and ` +
|
|
560
841
|
`${result.failed === 1 ? 'was' : 'were'} left out of the index; the warnings above name ` +
|
|
561
842
|
`${result.failed === 1 ? 'it' : 'them'}.\n`);
|
|
562
|
-
return 1;
|
|
563
843
|
}
|
|
564
|
-
return
|
|
844
|
+
return result.failed;
|
|
565
845
|
}
|
|
566
846
|
finally {
|
|
567
847
|
await cms.close();
|
|
568
848
|
}
|
|
569
849
|
}
|
|
850
|
+
async function importCommand({ args, configPath, flags }) {
|
|
851
|
+
const [file, ...extra] = args;
|
|
852
|
+
if (file === undefined) {
|
|
853
|
+
throw new Error('geekity import needs one archive: geekity import <file>.');
|
|
854
|
+
}
|
|
855
|
+
if (extra.length > 0) {
|
|
856
|
+
throw new Error(`geekity import takes one archive, and no plugin on this site adds "import ${file}".`);
|
|
857
|
+
}
|
|
858
|
+
const unsettled = resolveConfig({
|
|
859
|
+
...(await loadConfig(process.cwd(), configPath)),
|
|
860
|
+
watch: false,
|
|
861
|
+
});
|
|
862
|
+
const { contentDir, dataDir } = unsettled;
|
|
863
|
+
if (databaseInUse(dataDir) || (await isServing(dataDir))) {
|
|
864
|
+
process.stderr.write(`The site is running: ${dataDir} is in use. Stop it and run geekity import again.\n`);
|
|
865
|
+
return 1;
|
|
866
|
+
}
|
|
867
|
+
const archive = path.resolve(file);
|
|
868
|
+
const targets = { contentDir, dataDir };
|
|
869
|
+
const settings = createSettings({ config: unsettled });
|
|
870
|
+
const archived = await readSiteManifest(archive);
|
|
871
|
+
const { manifest } = archived;
|
|
872
|
+
const occupied = checkImportTargets(archived, targets, settings).filter((target) => target.state === 'occupied');
|
|
873
|
+
if (occupied.length > 0 && flags['replace'] !== true) {
|
|
874
|
+
process.stderr.write(`${occupied.map((target) => target.dir).join(' and ')} already ${occupied.length === 1 ? 'holds' : 'hold'} a site. ` +
|
|
875
|
+
'Import into empty folders, or give --replace to move what they hold into <dir>/.geekity-before-import-<time> first.\n');
|
|
876
|
+
return 1;
|
|
877
|
+
}
|
|
878
|
+
const staged = await stageSiteImport({ archive, archived, targets, settings });
|
|
879
|
+
const inEffect = await settleConfig(Object.freeze({ ...unsettled, contentDir: staged.content ?? contentDir }));
|
|
880
|
+
if (inEffect.baseUrl !== manifest.baseUrl && flags['new-base-url'] !== true) {
|
|
881
|
+
await discardStaging(staged);
|
|
882
|
+
process.stderr.write(`The base URL in effect is ${inEffect.baseUrl}, and the archive was exported from ${manifest.baseUrl}. ` +
|
|
883
|
+
'Actor ids are built from the base URL, so followers would not follow the site to a new address. ' +
|
|
884
|
+
`Set GEEKITY_BASE_URL, or baseUrl in the config, to ${manifest.baseUrl}, ` +
|
|
885
|
+
`or give --new-base-url to import it at ${inEffect.baseUrl}.\n`);
|
|
886
|
+
return 1;
|
|
887
|
+
}
|
|
888
|
+
for (const skipped of staged.skipped) {
|
|
889
|
+
process.stderr.write(`Left out ${skipped.path}: ${skipped.why}.\n`);
|
|
890
|
+
}
|
|
891
|
+
for (const aside of await placeSiteImport(staged, { stamp: compactTime(unsettled.now()) })) {
|
|
892
|
+
process.stdout.write(`Moved what was there into ${aside}.\n`);
|
|
893
|
+
}
|
|
894
|
+
process.stdout.write(`Restored ${count(manifest.files.length - staged.skipped.length, 'file')} from ${archive}.\n`);
|
|
895
|
+
const config = await settleConfig(unsettled);
|
|
896
|
+
if (flags['dev-mode'] === true) {
|
|
897
|
+
await setOrThrow(createSettings({ config }), 'dev_mode', { on: true });
|
|
898
|
+
process.stdout.write('Dev mode is on: nothing the site does is sent until `geekity dev-mode off`.\n');
|
|
899
|
+
}
|
|
900
|
+
const failures = await installArchivedPlugins(manifest, {
|
|
901
|
+
pluginsDir: config.pluginsDir,
|
|
902
|
+
registry: pluginRegistry(process.env),
|
|
903
|
+
coreVersion: ownManifest().version,
|
|
904
|
+
});
|
|
905
|
+
for (const plugin of manifest.plugins) {
|
|
906
|
+
if (plugin.source === 'folder' && !failures.some((failed) => failed.name === plugin.name)) {
|
|
907
|
+
process.stdout.write(`Installed ${plugin.name} ${plugin.version}.\n`);
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
await restoreEnabledPlugins(manifest, config.contentDir);
|
|
911
|
+
await rebuildDatabase(config);
|
|
912
|
+
await finishSiteImport(targets);
|
|
913
|
+
process.stdout.write(importNotes(manifest)
|
|
914
|
+
.map((note) => `${note}\n`)
|
|
915
|
+
.join(''));
|
|
916
|
+
for (const failed of failures)
|
|
917
|
+
process.stderr.write(`${pluginFailureLine(failed)}\n`);
|
|
918
|
+
return failures.length > 0 ? 1 : 0;
|
|
919
|
+
}
|
|
920
|
+
/**
|
|
921
|
+
* It runs beside a serving site: no migration runs and no database is opened
|
|
922
|
+
* but the queue, read-only, to count what waits in it.
|
|
923
|
+
*/
|
|
924
|
+
async function exportCommand({ configPath, flags }) {
|
|
925
|
+
const config = await loadResolvedConfig(configPath, (loaded) => ({ ...loaded, watch: false }));
|
|
926
|
+
const settings = createSettings({ config });
|
|
927
|
+
const plugins = await loadSitePlugins(config, settings);
|
|
928
|
+
if (flags['list'] === true) {
|
|
929
|
+
const declarations = siteDataFiles({ dataDir: config.dataDir, settings, plugins });
|
|
930
|
+
process.stdout.write(table([
|
|
931
|
+
...declarations.map((each) => [`data/${each.pattern}`, each.dataClass.kind, each.lost]),
|
|
932
|
+
['content/**', 'kept', 'The site: its documents, uploads and _data.'],
|
|
933
|
+
...CONTENT_SCRATCH_FILES.map((each) => [
|
|
934
|
+
`content/${each.pattern}`,
|
|
935
|
+
each.dataClass.kind,
|
|
936
|
+
each.lost,
|
|
937
|
+
]),
|
|
938
|
+
]));
|
|
939
|
+
return 0;
|
|
940
|
+
}
|
|
941
|
+
const plan = await planSiteExport({ config, settings, plugins }, {
|
|
942
|
+
withCredentials: flags['with-credentials'] === true,
|
|
943
|
+
withContent: flags['without-content'] !== true,
|
|
944
|
+
});
|
|
945
|
+
const { deliveries } = plan.site.pending;
|
|
946
|
+
process.stdout.write(`${count(deliveries, 'delivery is', 'deliveries are')} waiting in data/queue.sqlite. ` +
|
|
947
|
+
'They are not exported: before a move, wait until none are.\n' +
|
|
948
|
+
'The archive holds actor keys, password hashes and personal data. ' +
|
|
949
|
+
'Store it as carefully as data/.\n');
|
|
950
|
+
const now = config.now();
|
|
951
|
+
const out = path.resolve(text(flags, 'out') ?? exportFileName(config.baseUrl, now));
|
|
952
|
+
const manifest = await writeSiteExport(plan, { out, now });
|
|
953
|
+
for (const file of manifest.undeclared) {
|
|
954
|
+
process.stderr.write(`Left out ${file}: no declaration says what it is.\n`);
|
|
955
|
+
}
|
|
956
|
+
for (const entry of manifest.notCarried) {
|
|
957
|
+
process.stderr.write(`Left out ${entry.path}: it is ${entry.why}, and an export holds only regular files.\n`);
|
|
958
|
+
}
|
|
959
|
+
if (manifest.credentialsLeftOut.length > 0) {
|
|
960
|
+
process.stdout.write(`Credentials left out: ${manifest.credentialsLeftOut.join(', ')}. ` +
|
|
961
|
+
'--with-credentials includes them.\n');
|
|
962
|
+
}
|
|
963
|
+
const bytes = manifest.files.reduce((total, file) => total + file.size, 0);
|
|
964
|
+
process.stdout.write(`Wrote ${out}: ${count(manifest.files.length, 'file')}, ${count(bytes, 'byte')}.\n`);
|
|
965
|
+
return 0;
|
|
966
|
+
}
|
|
570
967
|
/** "1 follower", "2 followers". The plural is the singular plus s unless told. */
|
|
571
968
|
/** How many comments the files hold, whatever a moderator has done with them. */
|
|
572
969
|
function totalComments(admin) {
|
|
@@ -679,7 +1076,7 @@ async function serveWorker(configPath) {
|
|
|
679
1076
|
supervision: worker.supervision,
|
|
680
1077
|
});
|
|
681
1078
|
const { port } = await cms.serve();
|
|
682
|
-
if (
|
|
1079
|
+
if (await cms.settings.get(DEV_MODE.on)) {
|
|
683
1080
|
process.stdout.write('Dev mode is on: ActivityPub, webmentions, feed pings, IndexNow and email are held ' +
|
|
684
1081
|
'and recorded in data/dev-mode.jsonl. `geekity dev-mode off` takes the site live.\n');
|
|
685
1082
|
}
|
|
@@ -876,17 +1273,26 @@ function configFlag(argv) {
|
|
|
876
1273
|
}
|
|
877
1274
|
return undefined;
|
|
878
1275
|
}
|
|
1276
|
+
async function loadSitePlugins(config, settings) {
|
|
1277
|
+
const folderPlugins = await importPluginFolders(scanPluginFolders(config.pluginsDir));
|
|
1278
|
+
return sitePluginRegistry(config, folderPlugins, settings);
|
|
1279
|
+
}
|
|
879
1280
|
/**
|
|
880
1281
|
* Every command the site's available plugins add, from its config and its
|
|
881
1282
|
* plugins folder, longest words first.
|
|
882
1283
|
*/
|
|
883
1284
|
async function pluginCommands(config) {
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
.plugins.filter((entry) => entry.problem === undefined)
|
|
1285
|
+
return (await loadSitePlugins(config, createSettings({ config }))).plugins
|
|
1286
|
+
.filter((entry) => entry.problem === undefined)
|
|
887
1287
|
.flatMap((entry) => entry.commands.map((command) => ({ plugin: entry.plugin.name, command })))
|
|
888
1288
|
.sort((a, b) => b.command.words.length - a.command.words.length);
|
|
889
1289
|
}
|
|
1290
|
+
async function pluginExtends(first, words, configPath) {
|
|
1291
|
+
if (COMMANDS[first].sharedWithPlugins !== true || words.length < 2)
|
|
1292
|
+
return false;
|
|
1293
|
+
const found = await pluginCommands(await loadResolvedConfig(configPath));
|
|
1294
|
+
return found.some(({ command }) => command.words.every((word, index) => words[index] === word));
|
|
1295
|
+
}
|
|
890
1296
|
/**
|
|
891
1297
|
* Run a command a plugin added (decision-33). It needs no enabling: a
|
|
892
1298
|
* migration command runs before the plugin it prepares for is turned on.
|
|
@@ -896,12 +1302,20 @@ async function pluginCommands(config) {
|
|
|
896
1302
|
* version that kept its accounts in SQLite is migrated first. The comments
|
|
897
1303
|
* are migrated as a boot would migrate them for the same reason: a command
|
|
898
1304
|
* writing comments before any server has would otherwise meet ids the site
|
|
899
|
-
* refuses to store.
|
|
1305
|
+
* refuses to store. Plugin settings still in `site.json` move to
|
|
1306
|
+
* `data/plugins/<name>/` first, so the command reads what a boot would.
|
|
900
1307
|
*/
|
|
901
1308
|
async function pluginCommand(argv) {
|
|
902
1309
|
const configPath = configFlag(argv);
|
|
903
1310
|
const config = await loadResolvedConfig(configPath);
|
|
904
1311
|
const words = leadingWords(argv);
|
|
1312
|
+
migratePluginSettings({
|
|
1313
|
+
contentDir: config.contentDir,
|
|
1314
|
+
dataDir: config.dataDir,
|
|
1315
|
+
log: (line) => {
|
|
1316
|
+
console.log(line);
|
|
1317
|
+
},
|
|
1318
|
+
});
|
|
905
1319
|
const found = (await pluginCommands(config)).find(({ command }) => command.words.every((word, index) => words[index] === word));
|
|
906
1320
|
if (found === undefined) {
|
|
907
1321
|
throw new Error(`Unknown command "${words[0] ?? ''}". Run geekity --help to see what is available.`);
|