@jant/core 0.6.14 → 0.6.15
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/bin/commands/import-site.js +81 -13
- package/bin/commands/migrate.js +55 -0
- package/bin/commands/posts/rebuild-html.js +184 -0
- package/bin/commands/site/snapshot/import.js +14 -10
- package/bin/lib/d1-query.js +23 -5
- package/bin/lib/migration-runner.js +29 -7
- package/bin/lib/node-database.js +32 -0
- package/bin/lib/site-snapshot.js +347 -46
- package/bin/lib/sql-export.js +1 -1
- package/bin/lib/thread-collection-migration.js +326 -0
- package/dist/app-BxCOR3Uc.js +6 -0
- package/dist/{app-2i7-WQHg.js → app-C-oi_t8W.js} +7408 -6343
- package/dist/client/.vite/manifest.json +3 -3
- package/dist/client/_assets/client-B_eGKN5p.css +2 -0
- package/dist/client/_assets/{client-BvID5ucz.js → client-DxY5BFe8.js} +58 -37
- package/dist/client/_assets/client-auth-CakPESv9.js +5533 -0
- package/dist/{export-DWn149b7.js → export-CsFx6F_M.js} +1259 -125
- package/dist/{github-sync-Ckk0sJxK.js → github-sync-Cq1pzzOI.js} +1 -1
- package/dist/{github-sync-C0zyF6XS.js → github-sync-ppWXN3jb.js} +2 -2
- package/dist/index.js +3 -3
- package/dist/node.js +5 -5
- package/package.json +11 -10
- package/src/__tests__/bin/posts-rebuild-html.test.ts +137 -0
- package/src/__tests__/dev-navigation-defaults.test.ts +22 -0
- package/src/__tests__/export-hugo-build.test.ts +63 -4
- package/src/__tests__/export-import-roundtrip.test.ts +6 -4
- package/src/__tests__/export-service.test.ts +142 -9
- package/src/__tests__/helpers/app.ts +3 -0
- package/src/__tests__/helpers/export-fixtures.ts +2 -0
- package/src/__tests__/import-site-command.test.ts +65 -0
- package/src/__tests__/vite-config.test.ts +45 -0
- package/src/app.tsx +16 -3
- package/src/client/__tests__/collection-created-notice.test.ts +36 -0
- package/src/client/__tests__/collection-form-bridge.test.ts +10 -1
- package/src/client/__tests__/collection-page-actions.test.ts +71 -2
- package/src/client/__tests__/compose-bridge.test.ts +64 -0
- package/src/client/__tests__/feed-video-player.test.ts +16 -1
- package/src/client/__tests__/footnote-rail.test.ts +472 -0
- package/src/client/__tests__/hydrate-partial.test.ts +3 -0
- package/src/client/__tests__/toast.test.ts +18 -1
- package/src/client/collection-created-notice.ts +66 -0
- package/src/client/collection-form-bridge.ts +17 -0
- package/src/client/collection-navigation.ts +44 -0
- package/src/client/collection-page-actions.ts +57 -1
- package/src/client/components/__tests__/jant-collection-directory.test.ts +155 -6
- package/src/client/components/__tests__/jant-compose-dialog.test.ts +370 -5
- package/src/client/components/__tests__/jant-compose-editor.test.ts +97 -0
- package/src/client/components/__tests__/jant-compose-fullscreen.test.ts +104 -0
- package/src/client/components/__tests__/jant-config-editor.test.ts +405 -0
- package/src/client/components/__tests__/jant-media-lightbox.test.ts +121 -0
- package/src/client/components/__tests__/jant-nav-manager.test.ts +538 -2
- package/src/client/components/__tests__/jant-post-form.test.ts +2 -2
- package/src/client/components/__tests__/jant-post-menu.test.ts +47 -5
- package/src/client/components/__tests__/jant-settings-avatar.test.ts +2 -2
- package/src/client/components/__tests__/jant-settings-general.test.ts +3 -3
- package/src/client/components/collection-manager-types.ts +9 -3
- package/src/client/components/compose-types.ts +8 -0
- package/src/client/components/jant-collection-directory.ts +165 -30
- package/src/client/components/jant-command-palette.ts +2 -1
- package/src/client/components/jant-compose-dialog.ts +85 -21
- package/src/client/components/jant-compose-editor.ts +13 -7
- package/src/client/components/jant-compose-fullscreen.ts +24 -4
- package/src/client/components/jant-config-editor.ts +722 -0
- package/src/client/components/jant-media-lightbox.ts +100 -18
- package/src/client/components/jant-nav-manager.ts +1283 -54
- package/src/client/components/jant-post-form.ts +3 -3
- package/src/client/components/jant-post-menu.ts +86 -74
- package/src/client/components/nav-manager-types.ts +51 -2
- package/src/client/components/post-form-types.ts +1 -1
- package/src/client/compose-bridge.ts +4 -1
- package/src/client/feed-video-player.ts +62 -2
- package/src/client/footnote-rail.ts +478 -0
- package/src/client/hydrate-partial.ts +2 -0
- package/src/client/media-lightbox-events.ts +63 -0
- package/src/client/site-header-fragment.ts +38 -0
- package/src/client/tiptap/__tests__/blockquote-editing.test.ts +201 -0
- package/src/client/tiptap/__tests__/clear-formatting.test.ts +168 -0
- package/src/client/tiptap/__tests__/list-editing.test.ts +447 -0
- package/src/client/tiptap/__tests__/markdown-clipboard.test.ts +727 -4
- package/src/client/tiptap/__tests__/table-controls.test.ts +263 -0
- package/src/client/tiptap/__tests__/table-size-picker.test.ts +179 -0
- package/src/client/tiptap/bubble-menu.ts +88 -10
- package/src/client/tiptap/continuous-lists.ts +102 -0
- package/src/client/tiptap/create-editor.ts +3 -0
- package/src/client/tiptap/extensions.ts +14 -5
- package/src/client/tiptap/markdown-clipboard.ts +608 -11
- package/src/client/tiptap/slash-commands.ts +8 -1
- package/src/client/tiptap/structural-keymap.ts +211 -0
- package/src/client/tiptap/tab-indent.ts +8 -22
- package/src/client/tiptap/table-control-labels.ts +30 -0
- package/src/client/tiptap/table-controls.ts +537 -0
- package/src/client/tiptap/table-size-picker.ts +254 -0
- package/src/client/toast.ts +8 -6
- package/src/client-auth.ts +1 -0
- package/src/client.ts +1 -0
- package/src/db/__tests__/d1-query.test.ts +43 -1
- package/src/db/__tests__/migration-runner.test.ts +63 -0
- package/src/db/__tests__/migrations.test.ts +469 -0
- package/src/db/__tests__/thread-collection-migration.test.ts +364 -0
- package/src/db/migrations/0027_old_blue_blade.sql +39 -0
- package/src/db/migrations/0028_superb_post.sql +2 -0
- package/src/db/migrations/0029_boring_magma.sql +1 -0
- package/src/db/migrations/0030_typical_vivisector.sql +50 -0
- package/src/db/migrations/meta/0027_snapshot.json +2511 -0
- package/src/db/migrations/meta/0028_snapshot.json +2511 -0
- package/src/db/migrations/meta/0029_snapshot.json +2519 -0
- package/src/db/migrations/meta/0030_snapshot.json +2541 -0
- package/src/db/migrations/meta/_journal.json +28 -0
- package/src/db/migrations/pg/0025_moaning_epoch.sql +39 -0
- package/src/db/migrations/pg/0026_talented_killer_shrike.sql +2 -0
- package/src/db/migrations/pg/0027_short_cannonball.sql +1 -0
- package/src/db/migrations/pg/0028_perfect_sharon_carter.sql +27 -0
- package/src/db/migrations/pg/meta/0025_snapshot.json +3204 -0
- package/src/db/migrations/pg/meta/0026_snapshot.json +3204 -0
- package/src/db/migrations/pg/meta/0027_snapshot.json +3211 -0
- package/src/db/migrations/pg/meta/0028_snapshot.json +3248 -0
- package/src/db/migrations/pg/meta/_journal.json +28 -0
- package/src/db/pg/schema.ts +28 -20
- package/src/db/rehearsal-fixtures/demo-current.json +39 -4
- package/src/db/rehearsal-fixtures/demo-current.sql +121 -6
- package/src/db/schema.ts +28 -20
- package/src/i18n/__tests__/detect.test.ts +8 -2
- package/src/i18n/detect.ts +14 -5
- package/src/i18n/locales/public/en.po +133 -30
- package/src/i18n/locales/public/en.ts +1 -1
- package/src/i18n/locales/public/zh-Hans.po +128 -25
- package/src/i18n/locales/public/zh-Hans.ts +1 -1
- package/src/i18n/locales/public/zh-Hant.po +128 -25
- package/src/i18n/locales/public/zh-Hant.ts +1 -1
- package/src/i18n/locales/settings/en.po +513 -10
- package/src/i18n/locales/settings/en.ts +1 -1
- package/src/i18n/locales/settings/zh-Hans.po +515 -12
- package/src/i18n/locales/settings/zh-Hans.ts +1 -1
- package/src/i18n/locales/settings/zh-Hant.po +515 -12
- package/src/i18n/locales/settings/zh-Hant.ts +1 -1
- package/src/lib/__tests__/api-settings.test.ts +299 -0
- package/src/lib/__tests__/constants.test.ts +5 -0
- package/src/lib/__tests__/feed-policy.test.ts +25 -0
- package/src/lib/__tests__/footnotes-upgrade.test.ts +181 -0
- package/src/lib/__tests__/markdown-roundtrip-embed.test.ts +61 -0
- package/src/lib/__tests__/markdown-to-tiptap.test.ts +32 -4
- package/src/lib/__tests__/markdown.test.ts +8 -6
- package/src/lib/__tests__/navigation.test.ts +59 -2
- package/src/lib/__tests__/post-body-html.test.ts +176 -0
- package/src/lib/__tests__/post-display.test.ts +64 -0
- package/src/lib/__tests__/resolve-config.test.ts +113 -1
- package/src/lib/__tests__/summary.test.ts +82 -0
- package/src/lib/__tests__/timeline.test.ts +109 -70
- package/src/lib/__tests__/timezones.test.ts +31 -3
- package/src/lib/__tests__/tiptap-render.test.ts +268 -9
- package/src/lib/__tests__/tiptap-to-markdown.test.ts +6 -0
- package/src/lib/__tests__/view.test.ts +53 -0
- package/src/lib/__tests__/worker-response-cache.test.ts +18 -1
- package/src/lib/api-settings.ts +239 -12
- package/src/lib/collection-sort.ts +7 -5
- package/src/lib/constants.ts +2 -0
- package/src/lib/feed-path.ts +25 -0
- package/src/lib/feed-policy.ts +64 -0
- package/src/lib/footnotes.ts +264 -0
- package/src/lib/github-sync-site-config.ts +2 -0
- package/src/lib/hugo-markdown.ts +10 -3
- package/src/lib/jant-branding.ts +1 -0
- package/src/lib/markdown-manager.ts +188 -5
- package/src/lib/markdown.ts +10 -3
- package/src/lib/navigation.ts +16 -3
- package/src/lib/post-body-html.ts +131 -0
- package/src/lib/post-display.ts +7 -1
- package/src/lib/render.tsx +9 -2
- package/src/lib/resolve-config.ts +100 -16
- package/src/lib/schemas.ts +133 -1
- package/src/lib/settings-paths.ts +5 -0
- package/src/lib/site-skill.ts +78 -0
- package/src/lib/summary.ts +16 -5
- package/src/lib/timeline.ts +98 -122
- package/src/lib/timezones.ts +54 -14
- package/src/lib/tiptap-render.ts +355 -81
- package/src/lib/view.ts +30 -20
- package/src/lib/worker-response-cache.ts +11 -18
- package/src/middleware/__tests__/public-content-access.test.ts +91 -0
- package/src/middleware/config.ts +2 -2
- package/src/middleware/public-content-access.ts +87 -0
- package/src/node/__tests__/cli-export.test.ts +14 -0
- package/src/node/__tests__/cli-migrate.test.ts +6 -0
- package/src/node/__tests__/cli-site-snapshot.test.ts +205 -2
- package/src/node/__tests__/cli-snapshot-meta.test.ts +100 -0
- package/src/node/index.ts +2 -1
- package/src/preset.css +16 -2
- package/src/routes/__tests__/compose.test.ts +51 -0
- package/src/routes/__tests__/site-skill.test.ts +112 -0
- package/src/routes/api/__tests__/collections.test.ts +91 -19
- package/src/routes/api/__tests__/mcp.test.ts +65 -1
- package/src/routes/api/__tests__/nav-items.test.ts +91 -0
- package/src/routes/api/__tests__/public-access.test.ts +81 -0
- package/src/routes/api/__tests__/settings.test.ts +217 -0
- package/src/routes/api/collections.ts +22 -26
- package/src/routes/api/export.ts +2 -0
- package/src/routes/api/internal/__tests__/post-body-html.test.ts +163 -0
- package/src/routes/api/internal/__tests__/sites.test.ts +35 -2
- package/src/routes/api/internal/post-body-html.ts +43 -0
- package/src/routes/api/internal/sites.ts +24 -0
- package/src/routes/api/nav-items.ts +24 -1
- package/src/routes/api/posts.ts +2 -2
- package/src/routes/api/public/__tests__/archive.test.ts +35 -0
- package/src/routes/api/public/__tests__/posts.test.ts +208 -0
- package/src/routes/api/public/archive.ts +4 -0
- package/src/routes/api/public/posts.ts +41 -24
- package/src/routes/api/search.ts +3 -0
- package/src/routes/api/settings.ts +33 -0
- package/src/routes/auth/__tests__/setup.test.ts +7 -4
- package/src/routes/compose.tsx +2 -1
- package/src/routes/dash/settings.tsx +45 -2
- package/src/routes/feed/__tests__/feed.test.ts +210 -6
- package/src/routes/feed/feed.ts +23 -14
- package/src/routes/pages/__tests__/archive-params.test.ts +92 -3
- package/src/routes/pages/__tests__/collection-routing.test.ts +63 -5
- package/src/routes/pages/__tests__/collections.test.ts +9 -9
- package/src/routes/pages/__tests__/preview.test.ts +174 -0
- package/src/routes/pages/__tests__/search.test.ts +69 -0
- package/src/routes/pages/archive.tsx +27 -7
- package/src/routes/pages/collection.tsx +32 -19
- package/src/routes/pages/collections.tsx +6 -1
- package/src/routes/pages/page.tsx +83 -11
- package/src/routes/site-skill.ts +18 -0
- package/src/services/__tests__/auth.test.ts +7 -5
- package/src/services/__tests__/collection.test.ts +159 -44
- package/src/services/__tests__/navigation.test.ts +229 -21
- package/src/services/__tests__/post-timeline.test.ts +109 -30
- package/src/services/__tests__/post.test.ts +567 -5
- package/src/services/__tests__/search.test.ts +48 -1
- package/src/services/__tests__/settings.test.ts +8 -0
- package/src/services/__tests__/site-admin.test.ts +121 -1
- package/src/services/auth.ts +2 -2
- package/src/services/bootstrap.ts +3 -2
- package/src/services/collection.ts +226 -167
- package/src/services/export-theme/assets/client-site.css +1 -1
- package/src/services/export-theme/assets/client-site.js +46 -25
- package/src/services/export-theme/layouts/_default/list.html +18 -4
- package/src/services/export-theme/layouts/_default/rss.xml +8 -12
- package/src/services/export-theme/layouts/featured/list.html +5 -4
- package/src/services/export-theme/layouts/partials/featured-thread.html +56 -0
- package/src/services/export-theme/layouts/partials/footer.html +1 -1
- package/src/services/export-theme/layouts/partials/media-gallery.html +1 -0
- package/src/services/export-theme/styles/main.css +30 -2
- package/src/services/export.ts +91 -80
- package/src/services/mcp.ts +37 -27
- package/src/services/media.ts +1 -1
- package/src/services/navigation.ts +185 -46
- package/src/services/post.ts +874 -271
- package/src/services/search.ts +8 -2
- package/src/services/settings.ts +2 -10
- package/src/services/site-admin.ts +63 -43
- package/src/style-cjk-jp.css +1 -1
- package/src/style-cjk-kr.css +1 -1
- package/src/style-cjk-tc.css +1 -1
- package/src/style-cjk.css +1 -1
- package/src/styles/components.css +540 -0
- package/src/styles/site-media.css +111 -19
- package/src/styles/tokens.css +14 -9
- package/src/styles/ui.css +829 -29
- package/src/types/bindings.ts +3 -0
- package/src/types/config.ts +243 -12
- package/src/types/constants.ts +22 -1
- package/src/types/entities.ts +9 -8
- package/src/types/operations.ts +18 -10
- package/src/types/props.ts +8 -2
- package/src/types/raw-assets.d.ts +5 -0
- package/src/types/views.ts +16 -4
- package/src/ui/__tests__/font-themes.test.ts +42 -30
- package/src/ui/compose/ComposeDialog.tsx +92 -2
- package/src/ui/dash/appearance/NavigationContent.tsx +332 -4
- package/src/ui/dash/appearance/__tests__/NavigationContent.test.tsx +23 -0
- package/src/ui/dash/settings/ConfigEditorContent.tsx +578 -0
- package/src/ui/dash/settings/GeneralContent.tsx +15 -5
- package/src/ui/dash/settings/SettingsRootContent.tsx +21 -1
- package/src/ui/dash/settings/__tests__/ConfigEditorContent.test.tsx +98 -0
- package/src/ui/dash/settings/__tests__/SettingsRootContent.test.tsx +15 -0
- package/src/ui/feed/CuratedThreadPreview.tsx +16 -4
- package/src/ui/feed/LinkCard.tsx +2 -12
- package/src/ui/feed/NoteCard.tsx +10 -20
- package/src/ui/feed/QuoteCard.tsx +2 -12
- package/src/ui/feed/ThreadPreview.tsx +26 -34
- package/src/ui/feed/TimelineFeed.tsx +2 -2
- package/src/ui/feed/__tests__/thread-preview.test.ts +197 -56
- package/src/ui/feed/__tests__/timeline-cards.test.ts +178 -3
- package/src/ui/feed/thread-preview-state.ts +5 -7
- package/src/ui/font-themes.ts +74 -26
- package/src/ui/layouts/BaseLayout.tsx +22 -8
- package/src/ui/layouts/__tests__/BaseLayout.test.tsx +64 -1
- package/src/ui/pages/CollectionPage.tsx +101 -22
- package/src/ui/pages/CollectionsPage.tsx +3 -1
- package/src/ui/pages/PostPage.tsx +39 -12
- package/src/ui/pages/SearchPage.tsx +6 -14
- package/src/ui/pages/__tests__/ArchivePage.test.tsx +7 -0
- package/src/ui/pages/__tests__/PostPage.test.tsx +88 -0
- package/src/ui/shared/CollectionDirectory.tsx +13 -9
- package/src/ui/shared/CollectionsManager.tsx +17 -7
- package/src/ui/shared/DraftPreviewBar.tsx +33 -0
- package/src/ui/shared/HomePageBranding.tsx +2 -2
- package/src/ui/shared/MediaGallery.tsx +1 -0
- package/src/ui/shared/PostFooter.tsx +3 -1
- package/src/ui/shared/__tests__/home-page-branding.test.tsx +1 -1
- package/src/ui/shared/__tests__/media-gallery.test.ts +1 -0
- package/src/ui/shared/__tests__/navigation-labels.test.ts +2 -2
- package/src/ui/shared/__tests__/post-footer.test.ts +15 -0
- package/src/ui/shared/collection-management-labels.ts +33 -2
- package/src/ui/shared/navigation-labels.ts +2 -4
- package/src/ui/shared/post-article-attributes.ts +46 -0
- package/dist/app-DZDlmh7C.js +0 -6
- package/dist/client/_assets/client-Cevfpm8H.css +0 -2
- package/dist/client/_assets/client-auth-v3yvhbgZ.js +0 -4736
- package/src/client/tiptap/wrapping-input-rules.ts +0 -102
package/src/types/bindings.ts
CHANGED
|
@@ -40,6 +40,8 @@ export interface Bindings {
|
|
|
40
40
|
TIME_ZONE?: EnvBindingValue;
|
|
41
41
|
SITE_FOOTER?: EnvBindingValue;
|
|
42
42
|
NOINDEX?: EnvBindingValue;
|
|
43
|
+
PUBLIC_API_ENABLED?: EnvBindingValue;
|
|
44
|
+
RSS_FEEDS_ENABLED?: EnvBindingValue;
|
|
43
45
|
R2_PUBLIC_URL?: EnvBindingValue;
|
|
44
46
|
IMAGE_TRANSFORM_URL?: EnvBindingValue;
|
|
45
47
|
DEMO_EMAIL?: EnvBindingValue;
|
|
@@ -83,6 +85,7 @@ export interface Bindings {
|
|
|
83
85
|
SLUG_ID_LENGTH?: EnvBindingValue;
|
|
84
86
|
// RSS feed
|
|
85
87
|
RSS_FEED_LIMIT?: EnvBindingValue;
|
|
88
|
+
RSS_PUBLISH_DELAY_SECONDS?: EnvBindingValue;
|
|
86
89
|
// Node runtime database URL. SQLite uses file: URLs; Postgres uses
|
|
87
90
|
// postgres:/postgresql: URLs.
|
|
88
91
|
DATABASE_URL?: string;
|
package/src/types/config.ts
CHANGED
|
@@ -4,7 +4,48 @@
|
|
|
4
4
|
* Single Source of Truth for all configuration fields.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import
|
|
7
|
+
import {
|
|
8
|
+
MAX_SITE_DESCRIPTION_LENGTH,
|
|
9
|
+
MAX_SITE_FOOTER_LENGTH,
|
|
10
|
+
MAX_SITE_NAME_LENGTH,
|
|
11
|
+
type FeedKind,
|
|
12
|
+
} from "./constants.js";
|
|
13
|
+
|
|
14
|
+
export type ConfigEditorOptionsSource = "contentLanguage" | "timeZone";
|
|
15
|
+
|
|
16
|
+
export type ConfigEditorDefinition =
|
|
17
|
+
| {
|
|
18
|
+
type: "boolean";
|
|
19
|
+
}
|
|
20
|
+
| {
|
|
21
|
+
type: "string";
|
|
22
|
+
maxLength?: number;
|
|
23
|
+
}
|
|
24
|
+
| {
|
|
25
|
+
type: "number";
|
|
26
|
+
min?: number;
|
|
27
|
+
max?: number;
|
|
28
|
+
step?: number;
|
|
29
|
+
}
|
|
30
|
+
| {
|
|
31
|
+
type: "enum";
|
|
32
|
+
options: readonly string[];
|
|
33
|
+
optionsSource?: never;
|
|
34
|
+
}
|
|
35
|
+
| {
|
|
36
|
+
type: "enum";
|
|
37
|
+
options?: never;
|
|
38
|
+
optionsSource: ConfigEditorOptionsSource;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export interface ConfigEditorLinkDefinition {
|
|
42
|
+
type: "boolean" | "string";
|
|
43
|
+
settingsPath: string;
|
|
44
|
+
display: "value" | "configured";
|
|
45
|
+
fallbackKey?: "DEFAULT_THEME" | "DEFAULT_FONT_THEME";
|
|
46
|
+
fallbackValue?: string;
|
|
47
|
+
resettable?: boolean;
|
|
48
|
+
}
|
|
8
49
|
|
|
9
50
|
/**
|
|
10
51
|
* Configuration Registry - Single Source of Truth
|
|
@@ -20,6 +61,21 @@ interface ConfigField {
|
|
|
20
61
|
defaultValue: string;
|
|
21
62
|
envOnly: boolean;
|
|
22
63
|
internal?: boolean;
|
|
64
|
+
/** Another runtime field to inherit when this field has no own value. */
|
|
65
|
+
fallbackKey?: "PAGE_SIZE";
|
|
66
|
+
/**
|
|
67
|
+
* Explicitly opts a safe runtime setting into Config Editor.
|
|
68
|
+
*
|
|
69
|
+
* Omission is intentional: environment infrastructure, secrets, and
|
|
70
|
+
* internal state must never become editable merely because they are added
|
|
71
|
+
* to the broader config registry.
|
|
72
|
+
*/
|
|
73
|
+
editor?: ConfigEditorDefinition;
|
|
74
|
+
/**
|
|
75
|
+
* Adds a safe dedicated-page setting to the searchable Config Editor index
|
|
76
|
+
* without duplicating its specialized editing workflow.
|
|
77
|
+
*/
|
|
78
|
+
configEditorLink?: ConfigEditorLinkDefinition;
|
|
23
79
|
/**
|
|
24
80
|
* Environment variable names in resolution order.
|
|
25
81
|
*/
|
|
@@ -32,16 +88,31 @@ export const CONFIG_FIELDS = {
|
|
|
32
88
|
defaultValue: "Jant",
|
|
33
89
|
envOnly: false,
|
|
34
90
|
envKeys: ["SITE_NAME"],
|
|
91
|
+
editor: { type: "string", maxLength: MAX_SITE_NAME_LENGTH },
|
|
92
|
+
configEditorLink: {
|
|
93
|
+
type: "string",
|
|
94
|
+
settingsPath: "/settings/general",
|
|
95
|
+
display: "value",
|
|
96
|
+
resettable: true,
|
|
97
|
+
},
|
|
35
98
|
},
|
|
36
99
|
SITE_DESCRIPTION: {
|
|
37
100
|
defaultValue: "",
|
|
38
101
|
envOnly: false,
|
|
39
102
|
envKeys: ["SITE_DESCRIPTION"],
|
|
103
|
+
editor: { type: "string", maxLength: MAX_SITE_DESCRIPTION_LENGTH },
|
|
104
|
+
configEditorLink: {
|
|
105
|
+
type: "string",
|
|
106
|
+
settingsPath: "/settings/general",
|
|
107
|
+
display: "configured",
|
|
108
|
+
resettable: true,
|
|
109
|
+
},
|
|
40
110
|
},
|
|
41
111
|
SITE_LANGUAGE: {
|
|
42
112
|
defaultValue: "en",
|
|
43
113
|
envOnly: false,
|
|
44
114
|
envKeys: ["SITE_LANGUAGE"],
|
|
115
|
+
editor: { type: "enum", optionsSource: "contentLanguage" },
|
|
45
116
|
},
|
|
46
117
|
// Admin dashboard UI locale. Empty means "follow the content language"
|
|
47
118
|
// (resolved through the catalog fallback chain, i.e. today's behaviour).
|
|
@@ -49,16 +120,25 @@ export const CONFIG_FIELDS = {
|
|
|
49
120
|
defaultValue: "",
|
|
50
121
|
envOnly: false,
|
|
51
122
|
envKeys: ["DASHBOARD_LANGUAGE"],
|
|
123
|
+
editor: {
|
|
124
|
+
type: "enum",
|
|
125
|
+
options: ["", "en", "zh-Hans", "zh-Hant"],
|
|
126
|
+
},
|
|
52
127
|
},
|
|
53
128
|
CJK_SERIF_FONT: {
|
|
54
129
|
defaultValue: "off",
|
|
55
130
|
envOnly: false,
|
|
56
131
|
envKeys: ["CJK_SERIF_FONT"],
|
|
132
|
+
editor: {
|
|
133
|
+
type: "enum",
|
|
134
|
+
options: ["off", "zh-Hans", "zh-Hant", "ja", "ko"],
|
|
135
|
+
},
|
|
57
136
|
},
|
|
58
137
|
MAIN_RSS_FEED: {
|
|
59
138
|
defaultValue: "featured",
|
|
60
139
|
envOnly: false,
|
|
61
140
|
envKeys: ["MAIN_RSS_FEED"],
|
|
141
|
+
editor: { type: "enum", options: ["featured", "latest"] },
|
|
62
142
|
},
|
|
63
143
|
// Environment-only (deployment/infrastructure config)
|
|
64
144
|
DEFAULT_THEME: {
|
|
@@ -113,18 +193,23 @@ export const CONFIG_FIELDS = {
|
|
|
113
193
|
},
|
|
114
194
|
PAGE_SIZE: {
|
|
115
195
|
defaultValue: "50",
|
|
116
|
-
envOnly:
|
|
196
|
+
envOnly: false,
|
|
117
197
|
envKeys: ["PAGE_SIZE"],
|
|
198
|
+
editor: { type: "number", min: 1, max: 100, step: 1 },
|
|
118
199
|
},
|
|
119
200
|
SEARCH_PAGE_SIZE: {
|
|
120
201
|
defaultValue: "",
|
|
121
|
-
envOnly:
|
|
202
|
+
envOnly: false,
|
|
203
|
+
fallbackKey: "PAGE_SIZE",
|
|
122
204
|
envKeys: ["SEARCH_PAGE_SIZE"],
|
|
205
|
+
editor: { type: "number", min: 1, max: 100, step: 1 },
|
|
123
206
|
},
|
|
124
207
|
ARCHIVE_PAGE_SIZE: {
|
|
125
208
|
defaultValue: "",
|
|
126
|
-
envOnly:
|
|
209
|
+
envOnly: false,
|
|
210
|
+
fallbackKey: "PAGE_SIZE",
|
|
127
211
|
envKeys: ["ARCHIVE_PAGE_SIZE"],
|
|
212
|
+
editor: { type: "number", min: 1, max: 100, step: 1 },
|
|
128
213
|
},
|
|
129
214
|
STORAGE_DRIVER: {
|
|
130
215
|
defaultValue: "r2",
|
|
@@ -173,13 +258,15 @@ export const CONFIG_FIELDS = {
|
|
|
173
258
|
},
|
|
174
259
|
SUMMARY_MAX_PARAGRAPHS: {
|
|
175
260
|
defaultValue: "5",
|
|
176
|
-
envOnly:
|
|
261
|
+
envOnly: false,
|
|
177
262
|
envKeys: ["SUMMARY_MAX_PARAGRAPHS"],
|
|
263
|
+
editor: { type: "number", min: 1, max: 50, step: 1 },
|
|
178
264
|
},
|
|
179
265
|
SUMMARY_MAX_CHARS: {
|
|
180
266
|
defaultValue: "500",
|
|
181
|
-
envOnly:
|
|
267
|
+
envOnly: false,
|
|
182
268
|
envKeys: ["SUMMARY_MAX_CHARS"],
|
|
269
|
+
editor: { type: "number", min: 1, max: 1500, step: 1 },
|
|
183
270
|
},
|
|
184
271
|
SLUG_ID_LENGTH: {
|
|
185
272
|
defaultValue: "5",
|
|
@@ -188,8 +275,15 @@ export const CONFIG_FIELDS = {
|
|
|
188
275
|
},
|
|
189
276
|
RSS_FEED_LIMIT: {
|
|
190
277
|
defaultValue: "50",
|
|
191
|
-
envOnly:
|
|
278
|
+
envOnly: false,
|
|
192
279
|
envKeys: ["RSS_FEED_LIMIT"],
|
|
280
|
+
editor: { type: "number", min: 1, max: 200, step: 1 },
|
|
281
|
+
},
|
|
282
|
+
RSS_PUBLISH_DELAY_SECONDS: {
|
|
283
|
+
defaultValue: "300",
|
|
284
|
+
envOnly: false,
|
|
285
|
+
envKeys: ["RSS_PUBLISH_DELAY_SECONDS"],
|
|
286
|
+
editor: { type: "number", min: 0, max: 7200, step: 1 },
|
|
193
287
|
},
|
|
194
288
|
|
|
195
289
|
// Internal settings (DB-only, not configurable via env or settings UI)
|
|
@@ -197,31 +291,65 @@ export const CONFIG_FIELDS = {
|
|
|
197
291
|
defaultValue: "",
|
|
198
292
|
envOnly: false,
|
|
199
293
|
internal: true,
|
|
294
|
+
configEditorLink: {
|
|
295
|
+
type: "string",
|
|
296
|
+
settingsPath: "/settings/color-theme",
|
|
297
|
+
display: "value",
|
|
298
|
+
fallbackKey: "DEFAULT_THEME",
|
|
299
|
+
resettable: true,
|
|
300
|
+
},
|
|
200
301
|
},
|
|
201
302
|
CUSTOM_CSS: {
|
|
202
303
|
defaultValue: "",
|
|
203
304
|
envOnly: false,
|
|
204
305
|
internal: true,
|
|
306
|
+
configEditorLink: {
|
|
307
|
+
type: "string",
|
|
308
|
+
settingsPath: "/settings/custom-css",
|
|
309
|
+
display: "configured",
|
|
310
|
+
},
|
|
205
311
|
},
|
|
206
312
|
CUSTOM_HEAD_HTML: {
|
|
207
313
|
defaultValue: "",
|
|
208
314
|
envOnly: false,
|
|
209
315
|
internal: true,
|
|
316
|
+
configEditorLink: {
|
|
317
|
+
type: "string",
|
|
318
|
+
settingsPath: "/settings/code-injection",
|
|
319
|
+
display: "configured",
|
|
320
|
+
},
|
|
210
321
|
},
|
|
211
322
|
CUSTOM_BODY_END_HTML: {
|
|
212
323
|
defaultValue: "",
|
|
213
324
|
envOnly: false,
|
|
214
325
|
internal: true,
|
|
326
|
+
configEditorLink: {
|
|
327
|
+
type: "string",
|
|
328
|
+
settingsPath: "/settings/code-injection",
|
|
329
|
+
display: "configured",
|
|
330
|
+
},
|
|
215
331
|
},
|
|
216
332
|
SITE_AVATAR: {
|
|
217
333
|
defaultValue: "",
|
|
218
334
|
envOnly: false,
|
|
219
335
|
internal: true,
|
|
336
|
+
configEditorLink: {
|
|
337
|
+
type: "string",
|
|
338
|
+
settingsPath: "/settings/avatar",
|
|
339
|
+
display: "configured",
|
|
340
|
+
},
|
|
220
341
|
},
|
|
221
342
|
SHOW_HEADER_AVATAR: {
|
|
222
343
|
defaultValue: "",
|
|
223
344
|
envOnly: false,
|
|
224
345
|
internal: true,
|
|
346
|
+
configEditorLink: {
|
|
347
|
+
type: "boolean",
|
|
348
|
+
settingsPath: "/settings/avatar",
|
|
349
|
+
display: "value",
|
|
350
|
+
fallbackValue: "false",
|
|
351
|
+
resettable: true,
|
|
352
|
+
},
|
|
225
353
|
},
|
|
226
354
|
SITE_FAVICON_ICO: {
|
|
227
355
|
defaultValue: "",
|
|
@@ -242,31 +370,67 @@ export const CONFIG_FIELDS = {
|
|
|
242
370
|
defaultValue: "",
|
|
243
371
|
envOnly: false,
|
|
244
372
|
internal: true,
|
|
373
|
+
configEditorLink: {
|
|
374
|
+
type: "string",
|
|
375
|
+
settingsPath: "/settings/font-theme",
|
|
376
|
+
display: "value",
|
|
377
|
+
fallbackKey: "DEFAULT_FONT_THEME",
|
|
378
|
+
resettable: true,
|
|
379
|
+
},
|
|
245
380
|
},
|
|
246
381
|
THEME_MODE: {
|
|
247
382
|
defaultValue: "",
|
|
248
383
|
envOnly: false,
|
|
249
384
|
internal: true,
|
|
385
|
+
configEditorLink: {
|
|
386
|
+
type: "string",
|
|
387
|
+
settingsPath: "/settings/color-theme",
|
|
388
|
+
display: "value",
|
|
389
|
+
fallbackValue: "auto",
|
|
390
|
+
resettable: true,
|
|
391
|
+
},
|
|
250
392
|
},
|
|
251
393
|
TIME_ZONE: {
|
|
252
394
|
defaultValue: "UTC",
|
|
253
395
|
envOnly: false,
|
|
254
396
|
envKeys: ["TIME_ZONE"],
|
|
397
|
+
editor: { type: "enum", optionsSource: "timeZone" },
|
|
255
398
|
},
|
|
256
399
|
SITE_FOOTER: {
|
|
257
400
|
defaultValue: "",
|
|
258
401
|
envOnly: false,
|
|
259
402
|
envKeys: ["SITE_FOOTER"],
|
|
403
|
+
editor: { type: "string", maxLength: MAX_SITE_FOOTER_LENGTH },
|
|
404
|
+
configEditorLink: {
|
|
405
|
+
type: "string",
|
|
406
|
+
settingsPath: "/settings/general",
|
|
407
|
+
display: "configured",
|
|
408
|
+
resettable: true,
|
|
409
|
+
},
|
|
260
410
|
},
|
|
261
411
|
SHOW_JANT_BRANDING_ON_HOME: {
|
|
262
|
-
defaultValue: "",
|
|
412
|
+
defaultValue: "false",
|
|
263
413
|
envOnly: false,
|
|
264
414
|
envKeys: ["SHOW_JANT_BRANDING_ON_HOME"],
|
|
415
|
+
editor: { type: "boolean" },
|
|
265
416
|
},
|
|
266
417
|
NOINDEX: {
|
|
267
|
-
defaultValue: "",
|
|
418
|
+
defaultValue: "false",
|
|
268
419
|
envOnly: false,
|
|
269
420
|
envKeys: ["NOINDEX"],
|
|
421
|
+
editor: { type: "boolean" },
|
|
422
|
+
},
|
|
423
|
+
PUBLIC_API_ENABLED: {
|
|
424
|
+
defaultValue: "true",
|
|
425
|
+
envOnly: false,
|
|
426
|
+
envKeys: ["PUBLIC_API_ENABLED"],
|
|
427
|
+
editor: { type: "boolean" },
|
|
428
|
+
},
|
|
429
|
+
RSS_FEEDS_ENABLED: {
|
|
430
|
+
defaultValue: "true",
|
|
431
|
+
envOnly: false,
|
|
432
|
+
envKeys: ["RSS_FEEDS_ENABLED"],
|
|
433
|
+
editor: { type: "boolean" },
|
|
270
434
|
},
|
|
271
435
|
DISCOVERY_COMPOSE_OPEN_SHORTCUT_AT: {
|
|
272
436
|
defaultValue: "",
|
|
@@ -299,11 +463,21 @@ export const CONFIG_FIELDS = {
|
|
|
299
463
|
defaultValue: "false",
|
|
300
464
|
envOnly: false,
|
|
301
465
|
internal: true,
|
|
466
|
+
configEditorLink: {
|
|
467
|
+
type: "boolean",
|
|
468
|
+
settingsPath: "/settings/github-sync",
|
|
469
|
+
display: "value",
|
|
470
|
+
},
|
|
302
471
|
},
|
|
303
472
|
GITHUB_SYNC_REPO: {
|
|
304
473
|
defaultValue: "",
|
|
305
474
|
envOnly: false,
|
|
306
475
|
internal: true,
|
|
476
|
+
configEditorLink: {
|
|
477
|
+
type: "string",
|
|
478
|
+
settingsPath: "/settings/github-sync",
|
|
479
|
+
display: "configured",
|
|
480
|
+
},
|
|
307
481
|
},
|
|
308
482
|
GITHUB_SYNC_TOKEN: {
|
|
309
483
|
defaultValue: "",
|
|
@@ -433,6 +607,11 @@ export const CONFIG_FIELDS = {
|
|
|
433
607
|
defaultValue: "",
|
|
434
608
|
envOnly: false,
|
|
435
609
|
internal: true,
|
|
610
|
+
configEditorLink: {
|
|
611
|
+
type: "string",
|
|
612
|
+
settingsPath: "/settings/telegram",
|
|
613
|
+
display: "configured",
|
|
614
|
+
},
|
|
436
615
|
},
|
|
437
616
|
/** Per-site `secret_token` for a bring-your-own bot's webhook. */
|
|
438
617
|
TELEGRAM_BOT_WEBHOOK_SECRET: {
|
|
@@ -443,6 +622,52 @@ export const CONFIG_FIELDS = {
|
|
|
443
622
|
} as const satisfies Record<string, ConfigField>;
|
|
444
623
|
|
|
445
624
|
export type ConfigKey = keyof typeof CONFIG_FIELDS;
|
|
625
|
+
export type ConfigEditorKey = {
|
|
626
|
+
[K in ConfigKey]: (typeof CONFIG_FIELDS)[K] extends {
|
|
627
|
+
editor: ConfigEditorDefinition;
|
|
628
|
+
}
|
|
629
|
+
? K
|
|
630
|
+
: never;
|
|
631
|
+
}[ConfigKey];
|
|
632
|
+
|
|
633
|
+
export type ConfigEditorVisibleKey = {
|
|
634
|
+
[K in ConfigKey]: (typeof CONFIG_FIELDS)[K] extends
|
|
635
|
+
| { editor: ConfigEditorDefinition }
|
|
636
|
+
| { configEditorLink: ConfigEditorLinkDefinition }
|
|
637
|
+
? K
|
|
638
|
+
: never;
|
|
639
|
+
}[ConfigKey];
|
|
640
|
+
|
|
641
|
+
export type ConfigEditorResettableKey = {
|
|
642
|
+
[K in ConfigKey]: (typeof CONFIG_FIELDS)[K] extends {
|
|
643
|
+
editor: ConfigEditorDefinition;
|
|
644
|
+
}
|
|
645
|
+
? K
|
|
646
|
+
: (typeof CONFIG_FIELDS)[K] extends {
|
|
647
|
+
configEditorLink: { resettable: true };
|
|
648
|
+
}
|
|
649
|
+
? K
|
|
650
|
+
: never;
|
|
651
|
+
}[ConfigKey];
|
|
652
|
+
|
|
653
|
+
export interface ConfigEditorFieldState {
|
|
654
|
+
key: ConfigEditorVisibleKey;
|
|
655
|
+
mode: "edit" | "link";
|
|
656
|
+
type: ConfigEditorDefinition["type"];
|
|
657
|
+
value: string;
|
|
658
|
+
fallbackValue: string;
|
|
659
|
+
modified: boolean;
|
|
660
|
+
locked: boolean;
|
|
661
|
+
maxLength?: number;
|
|
662
|
+
min?: number;
|
|
663
|
+
max?: number;
|
|
664
|
+
step?: number;
|
|
665
|
+
options?: readonly string[];
|
|
666
|
+
settingsPath?: string;
|
|
667
|
+
display?: ConfigEditorLinkDefinition["display"];
|
|
668
|
+
resettable?: boolean;
|
|
669
|
+
fallbackKey?: "PAGE_SIZE";
|
|
670
|
+
}
|
|
446
671
|
export const THEME_MODES = ["auto", "light", "dark"] as const;
|
|
447
672
|
export type ThemeMode = (typeof THEME_MODES)[number];
|
|
448
673
|
|
|
@@ -465,7 +690,7 @@ export interface AppConfig {
|
|
|
465
690
|
* the translated catalog locales ("en", "zh-Hans", "zh-Hant").
|
|
466
691
|
*/
|
|
467
692
|
dashboardLanguage: string;
|
|
468
|
-
/** CJK
|
|
693
|
+
/** Optional CJK font fallback when the content language has no profile. */
|
|
469
694
|
cjkSerifFont: string;
|
|
470
695
|
mainRssFeed: FeedKind;
|
|
471
696
|
/** Canonical IANA timezone identifier used for date/time display. */
|
|
@@ -473,6 +698,10 @@ export interface AppConfig {
|
|
|
473
698
|
siteFooter: string;
|
|
474
699
|
showJantBrandingOnHome: boolean;
|
|
475
700
|
noindex: boolean;
|
|
701
|
+
/** Whether published content can be read from JSON APIs without authentication. */
|
|
702
|
+
publicApiEnabled: boolean;
|
|
703
|
+
/** Whether the site publishes its Atom feed endpoints. */
|
|
704
|
+
rssFeedsEnabled: boolean;
|
|
476
705
|
|
|
477
706
|
// Infrastructure (ENV only)
|
|
478
707
|
siteUrl: string;
|
|
@@ -492,17 +721,19 @@ export interface AppConfig {
|
|
|
492
721
|
/** Max upload file size in MB. Defaults to 500. */
|
|
493
722
|
uploadMaxFileSize: number;
|
|
494
723
|
|
|
495
|
-
// Summary extraction (ENV
|
|
724
|
+
// Summary extraction (DB > ENV > Default)
|
|
496
725
|
/** Max paragraphs to include in auto-extracted summary. Defaults to 5. */
|
|
497
726
|
summaryMaxParagraphs: number;
|
|
498
727
|
/** Max characters to include in auto-extracted summary. Defaults to 500. */
|
|
499
728
|
summaryMaxChars: number;
|
|
500
729
|
|
|
501
|
-
// Pagination/
|
|
730
|
+
// Pagination/feed (DB > ENV > Default)
|
|
502
731
|
pageSize: number;
|
|
503
732
|
searchPageSize: number;
|
|
504
733
|
archivePageSize: number;
|
|
505
734
|
rssFeedLimit: number;
|
|
735
|
+
/** Seconds a published Post waits before it can appear in Atom feeds. */
|
|
736
|
+
rssPublishDelaySeconds: number;
|
|
506
737
|
|
|
507
738
|
// Slug (ENV only)
|
|
508
739
|
/** Length of random IDs used in auto-generated slugs. Defaults to 5. */
|
package/src/types/constants.ts
CHANGED
|
@@ -29,7 +29,7 @@ export const COLLECTION_SORT_ORDERS = [
|
|
|
29
29
|
] as const;
|
|
30
30
|
export type CollectionSortOrder = (typeof COLLECTION_SORT_ORDERS)[number];
|
|
31
31
|
|
|
32
|
-
export const NAV_ITEM_TYPES = ["link", "system", "collection"] as const;
|
|
32
|
+
export const NAV_ITEM_TYPES = ["link", "system", "collection", "page"] as const;
|
|
33
33
|
export type NavItemType = (typeof NAV_ITEM_TYPES)[number];
|
|
34
34
|
|
|
35
35
|
export const NAV_ITEM_PLACEMENTS = ["header", "more"] as const;
|
|
@@ -81,6 +81,27 @@ export const SYSTEM_NAV_KEYS = {
|
|
|
81
81
|
}
|
|
82
82
|
>;
|
|
83
83
|
|
|
84
|
+
export interface DefaultNavigationProfile {
|
|
85
|
+
version: number;
|
|
86
|
+
systemKeys: readonly SystemNavKey[];
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Append-only default navigation profiles. A profile is materialized during
|
|
91
|
+
* initial setup/provisioning and incomplete-setup recovery. Existing rows are
|
|
92
|
+
* never removed, updated, or reordered to match a profile.
|
|
93
|
+
*/
|
|
94
|
+
export const DEFAULT_NAVIGATION_PROFILES = {
|
|
95
|
+
1: {
|
|
96
|
+
version: 1,
|
|
97
|
+
systemKeys: ["featured", "collections", "archive", "rss", "settings"],
|
|
98
|
+
},
|
|
99
|
+
} as const satisfies Record<number, DefaultNavigationProfile>;
|
|
100
|
+
|
|
101
|
+
export const DEFAULT_NAVIGATION_PROFILE_VERSION = 1 as const;
|
|
102
|
+
export const DEFAULT_NAVIGATION_PROFILE =
|
|
103
|
+
DEFAULT_NAVIGATION_PROFILES[DEFAULT_NAVIGATION_PROFILE_VERSION];
|
|
104
|
+
|
|
84
105
|
export const MAX_MEDIA_ATTACHMENTS = 20;
|
|
85
106
|
export const MAX_THREAD_POSTS = 20;
|
|
86
107
|
export const MAX_PINNED_POSTS = 3;
|
package/src/types/entities.ts
CHANGED
|
@@ -132,7 +132,7 @@ export interface Collection {
|
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
export interface CollectionDirectoryCollection extends Collection {
|
|
135
|
-
|
|
135
|
+
threadCount: number;
|
|
136
136
|
recentActivityAt: number;
|
|
137
137
|
}
|
|
138
138
|
|
|
@@ -166,9 +166,9 @@ export interface CollectionsDirectoryData {
|
|
|
166
166
|
directoryItems: CollectionDirectoryEntry[];
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
-
export interface
|
|
169
|
+
export interface ThreadCollection {
|
|
170
170
|
siteId: string;
|
|
171
|
-
|
|
171
|
+
threadId: string;
|
|
172
172
|
collectionId: string;
|
|
173
173
|
}
|
|
174
174
|
|
|
@@ -178,6 +178,7 @@ export interface NavItem {
|
|
|
178
178
|
type: NavItemType;
|
|
179
179
|
systemKey?: SystemNavKey;
|
|
180
180
|
collectionId?: string;
|
|
181
|
+
postId?: string;
|
|
181
182
|
label: string;
|
|
182
183
|
url: string;
|
|
183
184
|
placement: NavItemPlacement;
|
|
@@ -228,12 +229,12 @@ export interface ApiToken {
|
|
|
228
229
|
updatedAt: number;
|
|
229
230
|
}
|
|
230
231
|
|
|
231
|
-
/**
|
|
232
|
+
/** Bounded reply context for a thread root, used in timeline display. */
|
|
232
233
|
export interface ThreadTimelineContext {
|
|
233
|
-
/**
|
|
234
|
-
|
|
235
|
-
/**
|
|
236
|
-
|
|
234
|
+
/** Earliest published replies, in chronological order. */
|
|
235
|
+
leadingReplies: Post[];
|
|
236
|
+
/** Published replies immediately before latest, in chronological order. */
|
|
237
|
+
trailingReplies: Post[];
|
|
237
238
|
latestReply: Post;
|
|
238
239
|
totalReplyCount: number;
|
|
239
240
|
}
|
package/src/types/operations.ts
CHANGED
|
@@ -35,17 +35,17 @@ export interface TextAttachmentContent {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
|
-
* A single collection membership entry, with all the per-row metadata
|
|
39
|
-
* `
|
|
38
|
+
* A single Thread collection membership entry, with all the per-row metadata
|
|
39
|
+
* the `thread_collection` junction table carries. Used by the Hugo importer to
|
|
40
40
|
* restore per-entry `createdAt` / `position` / `pinnedAt` losslessly.
|
|
41
41
|
*/
|
|
42
|
-
export interface
|
|
42
|
+
export interface ThreadCollectionEntry {
|
|
43
43
|
collectionId: string;
|
|
44
|
-
/** Unix seconds — when the
|
|
44
|
+
/** Unix seconds — when the Thread was added to the collection. Defaults to now() when omitted. */
|
|
45
45
|
createdAt?: number;
|
|
46
46
|
/** Sort position within the collection. Defaults to append-at-end when omitted. */
|
|
47
47
|
position?: number;
|
|
48
|
-
/** Unix seconds when the
|
|
48
|
+
/** Unix seconds when the Thread was pinned in this specific collection; null means unpinned. */
|
|
49
49
|
pinnedAt?: number | null;
|
|
50
50
|
}
|
|
51
51
|
|
|
@@ -79,9 +79,10 @@ export interface CreatePost {
|
|
|
79
79
|
quoteText?: string;
|
|
80
80
|
rating?: number;
|
|
81
81
|
/**
|
|
82
|
-
* Simple slug/ID list
|
|
83
|
-
*
|
|
84
|
-
*
|
|
82
|
+
* Simple slug/ID list for the shared Thread collection set. Set this while
|
|
83
|
+
* creating a Thread root; reply creation rejects non-empty membership input.
|
|
84
|
+
* Uses `now()` for `createdAt` and append-at-end for `position`. For lossless
|
|
85
|
+
* import that preserves those fields, use `collectionEntries` instead.
|
|
85
86
|
*/
|
|
86
87
|
collectionIds?: string[];
|
|
87
88
|
/**
|
|
@@ -89,7 +90,7 @@ export interface CreatePost {
|
|
|
89
90
|
* `collectionIds` and restores per-entry `createdAt` / `position` /
|
|
90
91
|
* `pinnedAt` losslessly.
|
|
91
92
|
*/
|
|
92
|
-
collectionEntries?:
|
|
93
|
+
collectionEntries?: ThreadCollectionEntry[];
|
|
93
94
|
replyToId?: string;
|
|
94
95
|
quietReply?: boolean;
|
|
95
96
|
publishedAt?: number;
|
|
@@ -116,7 +117,7 @@ export interface UpdatePost {
|
|
|
116
117
|
quoteText?: string | null;
|
|
117
118
|
rating?: number | null;
|
|
118
119
|
collectionIds?: string[];
|
|
119
|
-
collectionEntries?:
|
|
120
|
+
collectionEntries?: ThreadCollectionEntry[];
|
|
120
121
|
publishedAt?: number;
|
|
121
122
|
attachments?: PostAttachmentInput[];
|
|
122
123
|
}
|
|
@@ -142,6 +143,13 @@ export type CreateNavItem =
|
|
|
142
143
|
url: string;
|
|
143
144
|
placement?: NavItemPlacement;
|
|
144
145
|
position?: string;
|
|
146
|
+
}
|
|
147
|
+
| {
|
|
148
|
+
type: "page";
|
|
149
|
+
postId: string;
|
|
150
|
+
label?: string;
|
|
151
|
+
placement?: NavItemPlacement;
|
|
152
|
+
position?: string;
|
|
145
153
|
};
|
|
146
154
|
|
|
147
155
|
export interface UpdateNavItem {
|
package/src/types/props.ts
CHANGED
|
@@ -30,6 +30,8 @@ export interface HomePageProps {
|
|
|
30
30
|
export interface PostPageProps {
|
|
31
31
|
post: PostView;
|
|
32
32
|
threadPosts?: PostView[];
|
|
33
|
+
/** Hide owner-only actions while preserving the public post rendering. */
|
|
34
|
+
isPreview?: boolean;
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
/** Props for the featured page component */
|
|
@@ -108,7 +110,10 @@ export interface CollectionPageProps {
|
|
|
108
110
|
defaultSort: CollectionSortOrder;
|
|
109
111
|
showRatingSort: boolean;
|
|
110
112
|
isAuthenticated: boolean;
|
|
113
|
+
isInNavigation?: boolean;
|
|
111
114
|
sitePathPrefix?: string;
|
|
115
|
+
/** Href for this collection selection's Atom feed when feeds are enabled. */
|
|
116
|
+
feedHref?: string;
|
|
112
117
|
}
|
|
113
118
|
|
|
114
119
|
/** Props for the collection editor page component */
|
|
@@ -123,6 +128,7 @@ export interface CollectionEditorPageProps {
|
|
|
123
128
|
export interface CollectionsPageProps {
|
|
124
129
|
items: CollectionDirectoryItem[];
|
|
125
130
|
isAuthenticated: boolean;
|
|
131
|
+
navigationCollectionIds?: string[];
|
|
126
132
|
sitePathPrefix?: string;
|
|
127
133
|
siteOrigin?: string;
|
|
128
134
|
}
|
|
@@ -179,8 +185,8 @@ export interface TimelineCardProps {
|
|
|
179
185
|
/** Props for thread inline preview */
|
|
180
186
|
export interface ThreadPreviewProps {
|
|
181
187
|
rootPost: PostView;
|
|
182
|
-
|
|
183
|
-
|
|
188
|
+
leadingReplies: PostView[];
|
|
189
|
+
trailingReplies: PostView[];
|
|
184
190
|
latestReply: PostView;
|
|
185
191
|
totalReplyCount: number;
|
|
186
192
|
}
|