@jant/core 0.6.16 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -11
- package/bin/commands/assets/upload.js +192 -15
- package/bin/commands/import-site.js +60 -4
- package/bin/commands/reset-password.js +21 -8
- package/bin/commands/site/snapshot/export.js +1 -1
- package/bin/commands/site/snapshot/import.js +1 -1
- package/bin/lib/d1-query.js +5 -16
- package/bin/lib/node-env.js +40 -4
- package/bin/lib/site-selection.js +85 -29
- package/bin/lib/wrangler-cli.js +28 -2
- package/bin/lib/wrangler-json.js +35 -0
- package/dist/{app-C7_4oab9.js → app-K_Aa1MMn.js} +52476 -13330
- package/dist/client/.vite/manifest.json +255 -90
- package/dist/client/_assets/chunks/confirm-D7GrwsCN.js +45 -0
- package/dist/client/_assets/chunks/create-editor-CD3FhrOB.js +257 -0
- package/dist/client/_assets/chunks/{native-DpcrFAPh.js → emoji-mart-C4RpRKcU.js} +716 -1
- package/dist/client/_assets/chunks/footnote-rail-CmeoVtnU.js +1 -0
- package/dist/client/_assets/chunks/heic-to-CuP2Qlsw.js +1 -0
- package/dist/client/_assets/chunks/jant-locale-picker-DL6mIOT5.js +69 -0
- package/dist/client/_assets/chunks/lit-DW8VmJAT.js +2 -0
- package/dist/client/_assets/chunks/mediabunny-DRaCQ1r-.js +31 -0
- package/dist/client/_assets/chunks/rolldown-runtime-hePW80VL.js +1 -0
- package/dist/client/_assets/chunks/settings-paths-BcdySNx6.js +84 -0
- package/dist/client/_assets/chunks/site-header-nav-DzXsFk05.js +1 -0
- package/dist/client/_assets/chunks/slug-format-CRXO1AL5.js +1 -0
- package/dist/client/_assets/chunks/slugify-373citbs.js +1 -0
- package/dist/client/_assets/chunks/sortable-list-CgaL2jCs.js +2 -0
- package/dist/client/_assets/chunks/types-D5iF3H1a.js +1 -0
- package/dist/client/_assets/chunks/unsafe-html-B5ZEXaxg.js +1 -0
- package/dist/client/_assets/chunks/unsafe-svg-0QCkP0vZ.js +2 -0
- package/dist/client/_assets/client-GiYENVw8.css +2 -0
- package/dist/client/_assets/client-VnFxJN7G.js +295 -0
- package/dist/client/_assets/client-auth-k8gJ6QJj.js +828 -0
- package/dist/client/_assets/client-author-DQ8R-8KR.css +2 -0
- package/dist/client/_assets/client-compose-B_kDtWkW.js +2004 -0
- package/dist/client/_assets/client-manage-M90aSTOk.js +2170 -0
- package/dist/client/_assets/client-settings-DfYs9n1F.js +1112 -0
- package/dist/{export-Dl5KCiEs.js → github-sync-BPAvT999.js} +2254 -107
- package/dist/index.js +2 -5
- package/dist/node.js +5 -7
- package/package.json +3 -3
- package/src/__tests__/auth-session-freshness.test.ts +57 -0
- package/src/__tests__/basecoat-variants.test.ts +121 -0
- package/src/__tests__/bin/assets-upload.test.ts +68 -0
- package/src/__tests__/export-hugo-build.test.ts +260 -0
- package/src/__tests__/export-service.test.ts +231 -0
- package/src/__tests__/helpers/component-css.ts +91 -0
- package/src/__tests__/helpers/db.ts +33 -0
- package/src/__tests__/helpers/export-fixtures.ts +3 -0
- package/src/__tests__/stylesheet-audience.test.ts +159 -0
- package/src/__tests__/stylesheet-breakpoints.test.ts +183 -0
- package/src/app.tsx +71 -16
- package/src/auth.ts +18 -1
- package/src/client/__tests__/collection-page-actions.test.ts +51 -2
- package/src/client/__tests__/compose-bridge-image-upload.test.ts +196 -0
- package/src/client/__tests__/compose-bridge-video-poster.test.ts +159 -0
- package/src/client/__tests__/compose-bridge.test.ts +272 -0
- package/src/client/__tests__/compose-launch.test.ts +62 -1
- package/src/client/__tests__/compose-shortcuts.test.ts +38 -9
- package/src/client/__tests__/compose-triggers.test.ts +90 -0
- package/src/client/__tests__/copy-field.test.ts +162 -0
- package/src/client/__tests__/custom-url-menu.test.ts +127 -6
- package/src/client/__tests__/image-processor.test.ts +324 -2
- package/src/client/__tests__/lazy-entries.test.ts +92 -0
- package/src/client/__tests__/media-scroll-hint.test.ts +155 -0
- package/src/client/__tests__/runtime-paths.test.ts +84 -0
- package/src/client/__tests__/smart-collection-page-actions.test.ts +158 -0
- package/src/client/__tests__/toast.test.ts +23 -0
- package/src/client/__tests__/video-processor-probe.test.ts +175 -0
- package/src/client/__tests__/video-processor.test.ts +181 -0
- package/src/client/audio-processor.ts +24 -15
- package/src/client/audio-waveform.ts +49 -0
- package/src/client/collection-dialog-host.ts +72 -0
- package/src/client/collection-navigation.ts +51 -16
- package/src/client/collection-page-actions.ts +26 -0
- package/src/client/components/__tests__/jant-collection-dialog.test.ts +329 -0
- package/src/client/components/__tests__/jant-collection-directory.test.ts +274 -10
- package/src/client/components/__tests__/jant-collection-form.test.ts +59 -178
- package/src/client/components/__tests__/jant-command-palette.test.ts +28 -0
- package/src/client/components/__tests__/jant-compose-dialog-draft-storage.test.ts +340 -0
- package/src/client/components/__tests__/jant-compose-dialog.test.ts +1250 -53
- package/src/client/components/__tests__/jant-compose-editor.test.ts +544 -40
- package/src/client/components/__tests__/jant-compose-fullscreen.test.ts +0 -1
- package/src/client/components/__tests__/jant-locale-picker.test.ts +207 -0
- package/src/client/components/__tests__/jant-nav-manager.test.ts +234 -15
- package/src/client/components/__tests__/jant-post-menu.test.ts +413 -2
- package/src/client/components/__tests__/jant-post-picker.test.ts +197 -0
- package/src/client/components/__tests__/jant-settings-avatar.test.ts +15 -12
- package/src/client/components/__tests__/jant-settings-general.test.ts +541 -172
- package/src/client/components/__tests__/jant-settings-language.test.ts +851 -0
- package/src/client/components/__tests__/jant-smart-collection-dialog.test.ts +665 -0
- package/src/client/components/collection-dialog-types.ts +49 -0
- package/src/client/components/collection-manager-types.ts +32 -1
- package/src/client/components/collection-types.ts +1 -15
- package/src/client/components/compose-types.ts +75 -1
- package/src/client/components/jant-collection-dialog.ts +722 -0
- package/src/client/components/jant-collection-directory.ts +567 -182
- package/src/client/components/jant-collection-form.ts +53 -232
- package/src/client/components/jant-command-palette.ts +100 -49
- package/src/client/components/jant-compose-dialog.ts +1486 -707
- package/src/client/components/jant-compose-editor.ts +673 -336
- package/src/client/components/jant-compose-fullscreen.ts +51 -43
- package/src/client/components/jant-config-editor.ts +65 -53
- package/src/client/components/jant-confirm-dialog.ts +13 -11
- package/src/client/components/jant-locale-picker.ts +418 -0
- package/src/client/components/jant-media-lightbox.ts +146 -136
- package/src/client/components/jant-nav-manager.ts +690 -366
- package/src/client/components/jant-post-menu.ts +1086 -282
- package/src/client/components/jant-post-picker.ts +324 -0
- package/src/client/components/jant-repo-picker.ts +138 -106
- package/src/client/components/jant-settings-avatar.ts +31 -27
- package/src/client/components/jant-settings-general.ts +617 -543
- package/src/client/components/jant-settings-language.ts +1087 -0
- package/src/client/components/jant-smart-collection-dialog.ts +1021 -0
- package/src/client/components/jant-text-preview.ts +94 -86
- package/src/client/components/nav-manager-types.ts +62 -1
- package/src/client/components/settings-types.ts +14 -29
- package/src/client/components/smart-collection-conditions.ts +285 -0
- package/src/client/components/smart-collection-dialog-types.ts +68 -0
- package/src/client/compose-bridge.ts +214 -141
- package/src/client/compose-launch.ts +76 -2
- package/src/client/compose-shortcuts.ts +6 -8
- package/src/client/compose-triggers.ts +50 -0
- package/src/client/copy-field.ts +108 -0
- package/src/client/custom-url-menu.ts +60 -4
- package/src/client/icons.ts +14 -0
- package/src/client/image-plan.ts +165 -0
- package/src/client/image-processor.ts +195 -117
- package/src/client/image-worker-client.ts +45 -0
- package/src/client/image-worker.ts +135 -0
- package/src/client/lazy-entries.ts +95 -0
- package/src/client/lazy-slugify.ts +2 -2
- package/src/client/media-scroll-hint.ts +43 -2
- package/src/client/mediabunny.ts +29 -0
- package/src/client/post-picker.ts +41 -0
- package/src/client/runtime-paths.ts +74 -1
- package/src/client/settings-bridge.ts +4 -10
- package/src/client/site-header-nav.js +18 -6
- package/src/client/smart-collection-dialog-host.ts +116 -0
- package/src/client/smart-collection-page-actions.ts +208 -0
- package/src/client/tiptap/__tests__/bubble-menu.test.ts +110 -0
- package/src/client/tiptap/__tests__/floating-position.test.ts +136 -1
- package/src/client/tiptap/__tests__/inline-image-upload.test.ts +37 -0
- package/src/client/tiptap/bubble-menu.ts +47 -16
- package/src/client/tiptap/floating-position.ts +216 -2
- package/src/client/tiptap/inline-image-upload.ts +7 -3
- package/src/client/tiptap/link-toolbar.ts +22 -9
- package/src/client/toast.ts +13 -0
- package/src/client/types/vite-worker.d.ts +12 -0
- package/src/client/upload-with-metadata.ts +3 -13
- package/src/client/video-processor.ts +351 -107
- package/src/client-auth.ts +14 -31
- package/src/client-compose.ts +19 -0
- package/src/client-manage.ts +13 -0
- package/src/client-settings.ts +14 -0
- package/src/client-site.ts +10 -3
- package/src/client.ts +4 -0
- package/src/db/__tests__/backfill-nav-label-mirrors.test.ts +149 -0
- package/src/db/__tests__/schema-enum-sources.test.ts +33 -0
- package/src/db/__tests__/smart-collection-placement.test.ts +402 -0
- package/src/db/backfills/0006_clear_mirrored_page_nav_labels.sql +31 -0
- package/src/db/migrations/0032_married_tomas.sql +3 -0
- package/src/db/migrations/0033_busy_johnny_storm.sql +198 -0
- package/src/db/migrations/0034_cheerful_rumiko_fujikawa.sql +35 -0
- package/src/db/migrations/meta/0032_snapshot.json +2582 -0
- package/src/db/migrations/meta/0033_snapshot.json +2816 -0
- package/src/db/migrations/meta/0034_snapshot.json +2816 -0
- package/src/db/migrations/meta/_journal.json +21 -0
- package/src/db/migrations/pg/0030_abandoned_nighthawk.sql +3 -0
- package/src/db/migrations/pg/0031_strong_ultimatum.sql +128 -0
- package/src/db/migrations/pg/0032_furry_multiple_man.sql +6 -0
- package/src/db/migrations/pg/meta/0030_snapshot.json +3329 -0
- package/src/db/migrations/pg/meta/0031_snapshot.json +3660 -0
- package/src/db/migrations/pg/meta/0032_snapshot.json +3660 -0
- package/src/db/migrations/pg/meta/_journal.json +21 -0
- package/src/db/pg/schema.ts +195 -27
- package/src/db/post-visibility.ts +117 -0
- package/src/db/schema.ts +222 -27
- package/src/i18n/__tests__/detect.test.ts +26 -81
- package/src/i18n/__tests__/supported-locales.test.ts +83 -0
- package/src/i18n/context.tsx +12 -2
- package/src/i18n/detect.ts +7 -66
- package/src/i18n/locales/glossary.zh-Hans.yml +44 -4
- package/src/i18n/locales/glossary.zh-Hant.yml +44 -4
- package/src/i18n/locales/public/en.po +490 -158
- package/src/i18n/locales/public/en.ts +1 -1
- package/src/i18n/locales/public/zh-Hans.po +487 -155
- package/src/i18n/locales/public/zh-Hans.ts +1 -1
- package/src/i18n/locales/public/zh-Hant.po +487 -155
- package/src/i18n/locales/public/zh-Hant.ts +1 -1
- package/src/i18n/locales/settings/en.po +551 -69
- package/src/i18n/locales/settings/en.ts +1 -1
- package/src/i18n/locales/settings/zh-Hans.po +597 -115
- package/src/i18n/locales/settings/zh-Hans.ts +1 -1
- package/src/i18n/locales/settings/zh-Hant.po +610 -128
- package/src/i18n/locales/settings/zh-Hant.ts +1 -1
- package/src/i18n/locales.ts +94 -0
- package/src/i18n/middleware.ts +12 -2
- package/src/i18n/supported-locales.ts +80 -0
- package/src/lib/__tests__/api-settings.test.ts +11 -2
- package/src/lib/__tests__/asset-path.test.ts +92 -0
- package/src/lib/__tests__/deferred.test.ts +90 -0
- package/src/lib/__tests__/discover-ping.test.ts +89 -0
- package/src/lib/__tests__/discover.test.ts +410 -0
- package/src/lib/__tests__/feed-policy.test.ts +26 -0
- package/src/lib/__tests__/feed.test.ts +1526 -15
- package/src/lib/__tests__/filter-dimensions.test.ts +341 -0
- package/src/lib/__tests__/hosted-signin.test.ts +1 -1
- package/src/lib/__tests__/http-cache.test.ts +162 -0
- package/src/lib/__tests__/jant-docs-dev.test.ts +21 -0
- package/src/lib/__tests__/jant-docs.test.ts +23 -0
- package/src/lib/__tests__/lang-detect.test.ts +231 -0
- package/src/lib/__tests__/media-helpers.test.ts +81 -0
- package/src/lib/__tests__/navigation.test.ts +135 -1
- package/src/lib/__tests__/resolve-config.test.ts +64 -3
- package/src/lib/__tests__/schemas.test.ts +42 -4
- package/src/lib/__tests__/site-unavailable-page.test.ts +25 -0
- package/src/lib/__tests__/slug.test.ts +70 -0
- package/src/lib/__tests__/slugify.test.ts +85 -0
- package/src/lib/__tests__/storage.test.ts +32 -0
- package/src/lib/__tests__/thread-fold.test.ts +113 -0
- package/src/lib/__tests__/upload-sideload.test.ts +14 -0
- package/src/lib/__tests__/url-fetch.test.ts +1 -2
- package/src/lib/__tests__/url.test.ts +78 -72
- package/src/lib/__tests__/view-language.test.ts +413 -0
- package/src/lib/__tests__/worker-response-cache.test.ts +90 -0
- package/src/lib/address.ts +57 -0
- package/src/lib/api-posts.ts +12 -0
- package/src/lib/asset-path.ts +98 -1
- package/src/lib/build-env.ts +16 -0
- package/src/lib/collection-groups.ts +5 -1
- package/src/lib/collection-paths.ts +3 -10
- package/src/lib/constants.ts +28 -3
- package/src/lib/copy-field.ts +36 -0
- package/src/lib/crypto.ts +40 -0
- package/src/lib/csp-builder.ts +2 -1
- package/src/lib/deferred.ts +79 -0
- package/src/lib/discover-ping.ts +141 -0
- package/src/lib/discover.ts +437 -0
- package/src/lib/env.ts +134 -0
- package/src/lib/errors.ts +33 -0
- package/src/lib/feed-policy.ts +236 -2
- package/src/lib/feed.ts +926 -73
- package/src/lib/filter-dimensions.ts +1349 -0
- package/src/lib/github-sync-site-config.ts +3 -0
- package/src/lib/hosted-signin.ts +1 -1
- package/src/lib/http-cache.ts +148 -0
- package/src/lib/hugo-markdown.ts +16 -0
- package/src/lib/icons.ts +9 -2
- package/src/lib/ids.ts +3 -0
- package/src/lib/jant-docs.ts +42 -0
- package/src/lib/lang-detect.ts +308 -0
- package/src/lib/media-helpers.ts +13 -1
- package/src/lib/navigation.ts +78 -11
- package/src/lib/pagination.ts +28 -24
- package/src/lib/per-language-surfaces.ts +67 -0
- package/src/lib/post-meta.ts +19 -0
- package/src/lib/render.tsx +55 -7
- package/src/lib/resolve-config.ts +53 -5
- package/src/lib/schemas.ts +201 -10
- package/src/lib/site-header-fragment.tsx +2 -1
- package/src/lib/site-unavailable-page.ts +47 -0
- package/src/lib/slug.ts +51 -7
- package/src/lib/slugify.ts +113 -0
- package/src/lib/startup-config.ts +4 -6
- package/src/lib/storage.ts +7 -0
- package/src/lib/summary.ts +50 -0
- package/src/lib/thread-fold.ts +161 -0
- package/src/lib/time.ts +32 -0
- package/src/lib/timeline.ts +42 -1
- package/src/lib/tiptap-render.ts +1 -2
- package/src/lib/upload.ts +16 -13
- package/src/lib/url.ts +139 -86
- package/src/lib/version.ts +10 -8
- package/src/lib/view-language.ts +436 -0
- package/src/lib/view.ts +51 -23
- package/src/lib/viewer-context.ts +62 -0
- package/src/middleware/__tests__/auth.test.ts +70 -2
- package/src/middleware/__tests__/cache-control.test.ts +71 -3
- package/src/middleware/__tests__/onboarding.test.ts +76 -5
- package/src/middleware/__tests__/secure-headers.test.ts +1 -1
- package/src/middleware/__tests__/session.test.ts +181 -33
- package/src/middleware/auth.ts +50 -31
- package/src/middleware/cache-control.ts +75 -10
- package/src/middleware/config.ts +6 -6
- package/src/middleware/error-handler.ts +12 -0
- package/src/middleware/onboarding.ts +32 -10
- package/src/middleware/secure-headers.ts +1 -1
- package/src/middleware/session.ts +96 -8
- package/src/node/__tests__/cli-migrate.test.ts +21 -19
- package/src/node/__tests__/cli-reset-password.test.ts +81 -8
- package/src/node/__tests__/cli-runtime-target.test.ts +48 -1
- package/src/node/__tests__/cli-site-selection.test.ts +128 -38
- package/src/node/__tests__/runtime.test.ts +37 -0
- package/src/node/index.ts +1 -0
- package/src/preset.css +76 -22
- package/src/routes/__tests__/feed-validator.test.ts +156 -0
- package/src/routes/api/__tests__/collections.test.ts +114 -0
- package/src/routes/api/__tests__/discover.test.ts +222 -0
- package/src/routes/api/__tests__/nav-items.test.ts +212 -2
- package/src/routes/api/__tests__/post-translations.test.ts +829 -0
- package/src/routes/api/__tests__/settings.test.ts +24 -3
- package/src/routes/api/__tests__/telegram.test.ts +6 -5
- package/src/routes/api/collections.ts +49 -6
- package/src/routes/api/custom-urls.ts +0 -1
- package/src/routes/api/discover.ts +95 -0
- package/src/routes/api/export.ts +3 -0
- package/src/routes/api/internal/__tests__/sites.test.ts +42 -2
- package/src/routes/api/nav-items.ts +55 -8
- package/src/routes/api/posts.ts +159 -0
- package/src/routes/api/public/__tests__/archive.test.ts +111 -0
- package/src/routes/api/public/archive.ts +77 -81
- package/src/routes/api/public/posts.ts +23 -6
- package/src/routes/api/smart-collections.ts +132 -0
- package/src/routes/api/telegram.ts +2 -40
- package/src/routes/api/uploads.ts +1 -2
- package/src/routes/auth/__tests__/setup-auth.test.ts +137 -0
- package/src/routes/auth/__tests__/setup-discover.test.ts +204 -0
- package/src/routes/auth/__tests__/setup-flow.test.ts +270 -0
- package/src/routes/auth/__tests__/setup-page.test.tsx +329 -0
- package/src/routes/auth/__tests__/setup-steps.test.ts +310 -0
- package/src/routes/auth/__tests__/setup.test.ts +278 -26
- package/src/routes/auth/__tests__/signin.test.ts +135 -0
- package/src/routes/auth/setup.tsx +934 -186
- package/src/routes/auth/signin.tsx +10 -8
- package/src/routes/compose.tsx +5 -0
- package/src/routes/dash/__tests__/custom-urls-archive.test.ts +44 -0
- package/src/routes/dash/__tests__/custom-urls-page.test.ts +49 -0
- package/src/routes/dash/__tests__/delete-account.test.ts +106 -0
- package/src/routes/dash/__tests__/settings-discover.test.ts +213 -0
- package/src/routes/dash/custom-urls.tsx +1 -37
- package/src/routes/dash/settings.tsx +502 -41
- package/src/routes/discover-announce.ts +96 -0
- package/src/routes/feed/__tests__/feed.test.ts +165 -2
- package/src/routes/feed/feed.ts +69 -40
- package/src/routes/feed/sitemap.ts +95 -11
- package/src/routes/pages/__tests__/archive-indexing.test.ts +200 -0
- package/src/routes/pages/__tests__/archive-params.test.ts +370 -6
- package/src/routes/pages/__tests__/collection-routing.test.ts +16 -0
- package/src/routes/pages/__tests__/collections-feed-links.test.ts +72 -0
- package/src/routes/pages/__tests__/collections.test.ts +9 -3
- package/src/routes/pages/__tests__/custom-archive-url.test.ts +119 -0
- package/src/routes/pages/__tests__/feed-autodiscovery.test.ts +148 -0
- package/src/routes/pages/__tests__/language-routing.test.ts +679 -0
- package/src/routes/pages/__tests__/post-preview-partial.test.ts +96 -0
- package/src/routes/pages/__tests__/smart-collection.test.ts +298 -0
- package/src/routes/pages/__tests__/subscribe.test.ts +248 -0
- package/src/routes/pages/archive.tsx +471 -369
- package/src/routes/pages/collection.tsx +94 -96
- package/src/routes/pages/collections.tsx +38 -50
- package/src/routes/pages/featured.tsx +32 -13
- package/src/routes/pages/home.tsx +25 -6
- package/src/routes/pages/language.tsx +113 -0
- package/src/routes/pages/latest.tsx +26 -16
- package/src/routes/pages/new.tsx +3 -0
- package/src/routes/pages/page.tsx +178 -17
- package/src/routes/pages/partials.tsx +41 -0
- package/src/routes/pages/search.tsx +18 -3
- package/src/routes/pages/smart-collection.tsx +340 -0
- package/src/routes/pages/subscribe.tsx +182 -0
- package/src/runtime/__tests__/index.test.ts +19 -0
- package/src/runtime/__tests__/node.test.ts +129 -4
- package/src/runtime/cloudflare.ts +21 -2
- package/src/runtime/index.ts +27 -1
- package/src/runtime/node.ts +18 -1
- package/src/runtime/site.ts +95 -24
- package/src/services/__tests__/auth.test.ts +116 -7
- package/src/services/__tests__/collection.test.ts +108 -4
- package/src/services/__tests__/language.test.ts +495 -0
- package/src/services/__tests__/navigation.test.ts +213 -10
- package/src/services/__tests__/path.test.ts +180 -0
- package/src/services/__tests__/post-language.test.ts +830 -0
- package/src/services/__tests__/post.test.ts +46 -9
- package/src/services/__tests__/settings.test.ts +228 -17
- package/src/services/__tests__/site-admin.test.ts +5 -5
- package/src/services/__tests__/smart-collection.test.ts +651 -0
- package/src/services/about-page.ts +22 -1
- package/src/services/auth.ts +51 -49
- package/src/services/bootstrap.ts +188 -38
- package/src/services/collection-directory-position.ts +76 -0
- package/src/services/collection.ts +331 -46
- package/src/services/custom-url.ts +27 -22
- package/src/services/export-theme/assets/client-site.css +1 -1
- package/src/services/export-theme/assets/client-site.js +123 -123
- package/src/services/export-theme/layouts/_default/rss.xml +77 -1
- package/src/services/export-theme/layouts/partials/feed-post-content.xml +105 -2
- package/src/services/export-theme/layouts/partials/media-gallery.html +35 -21
- package/src/services/export-theme/layouts/partials/pagination.html +14 -13
- package/src/services/export-theme/layouts/partials/post-card.html +8 -4
- package/src/services/export-theme/layouts/partials/reply.html +2 -1
- package/src/services/export-theme/layouts/partials/thread-preview.html +40 -30
- package/src/services/export-theme/styles/main.css +13 -1
- package/src/services/export.ts +278 -19
- package/src/services/index.ts +34 -3
- package/src/services/language.ts +412 -0
- package/src/services/mcp.ts +3 -1
- package/src/services/media.ts +14 -6
- package/src/services/navigation.ts +429 -67
- package/src/services/path.ts +221 -6
- package/src/services/post.ts +1021 -152
- package/src/services/search.ts +39 -2
- package/src/services/settings.ts +238 -43
- package/src/services/site-admin.ts +24 -7
- package/src/services/site.ts +77 -1
- package/src/services/smart-collection.ts +636 -0
- package/src/services/telegram.ts +20 -22
- package/src/services/upload-session.ts +1 -3
- package/src/style-author.css +27 -0
- package/src/styles/components-author.css +1622 -0
- package/src/styles/components.css +24 -1571
- package/src/styles/site-media.css +16 -2
- package/src/styles/tokens.css +82 -12
- package/src/styles/ui-author.css +7602 -0
- package/src/styles/ui.css +1087 -7219
- package/src/types/app-context.ts +7 -0
- package/src/types/bindings.ts +3 -0
- package/src/types/config.ts +94 -15
- package/src/types/constants.ts +188 -16
- package/src/types/entities.ts +87 -1
- package/src/types/operations.ts +64 -2
- package/src/types/props.ts +157 -31
- package/src/types/views.ts +55 -1
- package/src/ui/__tests__/font-themes.test.ts +52 -12
- package/src/ui/compose/ComposeDialog.tsx +201 -7
- package/src/ui/compose/ComposePrompt.tsx +1 -5
- package/src/ui/compose/__tests__/ComposeDialog.test.tsx +125 -0
- package/src/ui/dash/appearance/AdvancedContent.tsx +2 -2
- package/src/ui/dash/appearance/CodeInjectionContent.tsx +12 -16
- package/src/ui/dash/appearance/NavigationContent.tsx +117 -16
- package/src/ui/dash/appearance/__tests__/NavigationContent.test.tsx +33 -11
- package/src/ui/dash/appearance/__tests__/system-nav-descriptions.test.ts +44 -0
- package/src/ui/dash/appearance/system-nav-descriptions.ts +75 -0
- package/src/ui/dash/settings/AccountMenuContent.tsx +2 -2
- package/src/ui/dash/settings/ApiTokensContent.tsx +2 -1
- package/src/ui/dash/settings/ConfigEditorContent.tsx +35 -16
- package/src/ui/dash/settings/GeneralContent.tsx +275 -113
- package/src/ui/dash/settings/LanguageContent.tsx +409 -0
- package/src/ui/dash/settings/SettingsRootContent.tsx +19 -1
- package/src/ui/dash/settings/__tests__/GeneralContent.test.tsx +324 -4
- package/src/ui/dash/settings/__tests__/LanguageContent.test.tsx +144 -0
- package/src/ui/dash/settings/__tests__/discover-copy.test.ts +66 -0
- package/src/ui/dash/settings/discover-copy.ts +116 -0
- package/src/ui/feed/LinkCard.tsx +55 -45
- package/src/ui/feed/NoteCard.tsx +9 -4
- package/src/ui/feed/PostStatusBadges.tsx +90 -43
- package/src/ui/feed/QuoteCard.tsx +55 -30
- package/src/ui/feed/ThreadPreview.tsx +6 -2
- package/src/ui/feed/__tests__/thread-preview.test.ts +13 -16
- package/src/ui/feed/__tests__/timeline-cards.test.ts +314 -49
- package/src/ui/feed/thread-preview-state.ts +20 -6
- package/src/ui/font-themes.ts +39 -29
- package/src/ui/layouts/BaseLayout.tsx +155 -10
- package/src/ui/layouts/SiteLayout.tsx +192 -34
- package/src/ui/layouts/__tests__/BaseLayout.test.tsx +196 -17
- package/src/ui/layouts/__tests__/SiteLayout.test.tsx +109 -85
- package/src/ui/pages/ArchivePage.tsx +282 -289
- package/src/ui/pages/CollectionPage.tsx +86 -76
- package/src/ui/pages/CollectionsPage.tsx +5 -0
- package/src/ui/pages/ComposePage.tsx +8 -0
- package/src/ui/pages/PostPage.tsx +47 -0
- package/src/ui/pages/SearchPage.tsx +3 -3
- package/src/ui/pages/SmartCollectionPage.tsx +434 -0
- package/src/ui/pages/SubscribePage.tsx +236 -0
- package/src/ui/pages/__tests__/ArchivePage.test.tsx +65 -9
- package/src/ui/pages/__tests__/collections-directory-rows.test.tsx +92 -0
- package/src/ui/pages/__tests__/collections-view-links.test.tsx +81 -0
- package/src/ui/shared/CollectionDirectory.tsx +178 -3
- package/src/ui/shared/CollectionsManager.tsx +70 -17
- package/src/ui/shared/CopyField.tsx +127 -0
- package/src/ui/shared/EmptyPostContent.tsx +23 -0
- package/src/ui/shared/MediaGallery.tsx +125 -46
- package/src/ui/shared/Pagination.tsx +20 -5
- package/src/ui/shared/PostFooter.tsx +20 -11
- package/src/ui/shared/__tests__/archive-labels.test.ts +100 -0
- package/src/ui/shared/__tests__/media-gallery.test.ts +210 -2
- package/src/ui/shared/__tests__/navigation-labels.test.ts +16 -22
- package/src/ui/shared/__tests__/pagination.test.ts +38 -24
- package/src/ui/shared/__tests__/post-footer.test.ts +32 -0
- package/src/ui/shared/archive-labels.ts +98 -0
- package/src/ui/shared/collection-management-labels.ts +94 -16
- package/src/ui/shared/navigation-labels.ts +45 -71
- package/src/ui/shared/post-article-attributes.ts +2 -0
- package/src/ui/shared/smart-collection-labels.ts +343 -0
- package/dist/app-C75Zc8dD.js +0 -6
- package/dist/client/_assets/chunks/heic-to-DUUaO23q.js +0 -1
- package/dist/client/_assets/chunks/module-DcsAZQZ_.js +0 -716
- package/dist/client/_assets/chunks/url-CU9pEbk5.js +0 -1
- package/dist/client/_assets/client-Bq0vre8Y.js +0 -296
- package/dist/client/_assets/client-D3VZyG4L.css +0 -2
- package/dist/client/_assets/client-auth-F2rb9WfF.js +0 -5571
- package/dist/env-BPYViDJJ.js +0 -281
- package/dist/github-api-BNF35Lkx.js +0 -176
- package/dist/github-app-DdiD-bC4.js +0 -275
- package/dist/github-sync-Bqg62IvV.js +0 -4
- package/dist/github-sync-HdK2EgvJ.js +0 -431
- package/dist/url-CbLAtlZe.js +0 -900
- package/src/client/__tests__/collection-created-notice.test.ts +0 -36
- package/src/client/__tests__/collection-form-bridge.test.ts +0 -216
- package/src/client/__tests__/post-form-bridge.test.ts +0 -82
- package/src/client/collection-created-notice.ts +0 -66
- package/src/client/collection-form-bridge.ts +0 -191
- package/src/client/components/__tests__/jant-post-form.test.ts +0 -193
- package/src/client/components/jant-post-form.ts +0 -422
- package/src/client/components/post-form-template.ts +0 -352
- package/src/client/components/post-form-types.ts +0 -96
- package/src/client/media-metadata.ts +0 -247
- package/src/client/post-form-bridge.ts +0 -193
- package/src/ui/pages/CollectionEditorPage.tsx +0 -175
package/src/lib/url.ts
CHANGED
|
@@ -2,16 +2,6 @@
|
|
|
2
2
|
* URL Utilities
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import limax from "limax";
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
HAN_RE,
|
|
9
|
-
HANGUL_RE,
|
|
10
|
-
KANA_RE,
|
|
11
|
-
hangulToLatin,
|
|
12
|
-
kanaToRomaji,
|
|
13
|
-
} from "./translit.js";
|
|
14
|
-
|
|
15
5
|
function normalizeSitePathname(pathname: string): string {
|
|
16
6
|
if (pathname === "/" || pathname === "") return "";
|
|
17
7
|
const trimmed = pathname.replace(/\/+$/, "");
|
|
@@ -141,97 +131,160 @@ export function toSameSitePath(url: string, siteOrigin: string): string | null {
|
|
|
141
131
|
return `${parsed.pathname}${parsed.search}${parsed.hash}` || "/";
|
|
142
132
|
}
|
|
143
133
|
|
|
144
|
-
const HAN_GLOBAL_RE = /\p{Script=Han}/gu;
|
|
145
|
-
const CONTENT_CHAR_RE = /[\p{L}\p{N}]/u;
|
|
146
|
-
const ASCII_ALNUM_RE = /[a-zA-Z0-9]/;
|
|
147
|
-
|
|
148
134
|
/**
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
* lost (e.g. mixed kanji+kana Japanese where the semantic core is kanji, or
|
|
152
|
-
* scripts limax drops entirely) and `slugify` returns "" so callers fall back
|
|
153
|
-
* to their random-ID path instead of shipping a garbled slug.
|
|
135
|
+
* Any `scheme:` at the start. `mailto:` and `tel:` address something real but
|
|
136
|
+
* never a page here, and an unrecognized scheme must not be read as a path.
|
|
154
137
|
*/
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
if (!CONTENT_CHAR_RE.test(char)) continue;
|
|
175
|
-
content++;
|
|
176
|
-
if (KANA_RE.test(char) || HANGUL_RE.test(char)) {
|
|
177
|
-
covered++;
|
|
178
|
-
} else if (japanese && HAN_RE.test(char)) {
|
|
179
|
-
// Kanji in a kana-containing title is dropped, never pinyin-read.
|
|
180
|
-
} else if (isCharCovered(char)) {
|
|
181
|
-
covered++;
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
return content === 0 ? 0 : covered / content;
|
|
138
|
+
const ANY_SCHEME_RE = /^[a-z][a-z0-9+.-]*:/i;
|
|
139
|
+
|
|
140
|
+
export interface InternalPathOptions {
|
|
141
|
+
/**
|
|
142
|
+
* Origins this site answers on. Pass the configured one *and* the origin of
|
|
143
|
+
* the current request: a hosted site is often reached on a custom domain the
|
|
144
|
+
* canonical URL knows nothing about.
|
|
145
|
+
*/
|
|
146
|
+
siteOrigins?: readonly string[];
|
|
147
|
+
/** Public site path prefix, such as `/blog`. */
|
|
148
|
+
sitePathPrefix?: string;
|
|
149
|
+
/**
|
|
150
|
+
* Language URL prefixes the site serves, without slashes (`["en", "ja"]`).
|
|
151
|
+
* A leading one is removed, because `/en/about` and `/about` are the same
|
|
152
|
+
* page seen from two views.
|
|
153
|
+
*/
|
|
154
|
+
languagePrefixes?: readonly string[];
|
|
155
|
+
/** Keep `?query` and `#hash`. Off by default: they name a spot, not a page. */
|
|
156
|
+
keepQuery?: boolean;
|
|
185
157
|
}
|
|
186
158
|
|
|
187
159
|
/**
|
|
188
|
-
*
|
|
160
|
+
* Whether a string is meant as an address rather than as search words.
|
|
189
161
|
*
|
|
190
|
-
*
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
* limax. When the title contains kana it is treated as Japanese and Han
|
|
194
|
-
* characters are dropped rather than misread as Chinese pinyin; Han without
|
|
195
|
-
* kana is treated as Chinese.
|
|
196
|
-
*
|
|
197
|
-
* Returns `""` when transliteration would lose too much of the title (see
|
|
198
|
-
* `SLUG_COVERAGE_THRESHOLD`) — every caller treats an empty base as "no
|
|
199
|
-
* usable title" and falls back to a random ID, which beats publishing a
|
|
200
|
-
* garbled slug.
|
|
201
|
-
*
|
|
202
|
-
* @param text - The text to convert to a slug
|
|
203
|
-
* @returns The slugified string, or `""` when no usable slug can be derived
|
|
162
|
+
* Deliberately narrow — a leading slash or a full `http(s)` URL. Anything
|
|
163
|
+
* looser would swallow real queries: a search for "about" is not a search for
|
|
164
|
+
* `/about`.
|
|
204
165
|
*
|
|
166
|
+
* @param input - What the author typed or pasted
|
|
167
|
+
* @returns True when the input should be resolved instead of searched
|
|
205
168
|
* @example
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
* //
|
|
169
|
+
* looksLikeAddress("/about"); // true
|
|
170
|
+
* looksLikeAddress("https://example.com/about"); // true
|
|
171
|
+
* looksLikeAddress("about"); // false
|
|
172
|
+
*/
|
|
173
|
+
export function looksLikeAddress(input: string): boolean {
|
|
174
|
+
const trimmed = input.trim();
|
|
175
|
+
return trimmed.startsWith("/") || isFullUrl(trimmed);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Convert an address the author pasted into an internal app path.
|
|
209
180
|
*
|
|
210
|
-
*
|
|
211
|
-
*
|
|
181
|
+
* Accepts what a browser address bar would produce — a full URL on one of the
|
|
182
|
+
* site's own origins, or a path — and returns the path the router resolves
|
|
183
|
+
* against: no site path prefix, no language prefix, rooted at `/`. Returns
|
|
184
|
+
* `null` for anything that is not a page on this site, so callers can tell an
|
|
185
|
+
* external link apart from a bad one.
|
|
212
186
|
*
|
|
213
|
-
*
|
|
214
|
-
*
|
|
187
|
+
* Case is left alone; storage-level normalization belongs to the path
|
|
188
|
+
* registry, which lowercases on its own terms.
|
|
215
189
|
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
190
|
+
* A full URL has to sit inside the deployment to count. A typed path does not:
|
|
191
|
+
* `/about` on a site served from `/blog` is the About page, because that is
|
|
192
|
+
* what someone typing it means.
|
|
218
193
|
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
*
|
|
194
|
+
* @param input - A full URL, or a path
|
|
195
|
+
* @param options - The site's origins, prefixes, and what to keep
|
|
196
|
+
* @returns Internal path rooted at `/`, or `null` when the address is not ours
|
|
197
|
+
* @example
|
|
198
|
+
* toInternalPath("https://example.com/blog/en/about", {
|
|
199
|
+
* siteOrigins: ["https://example.com"],
|
|
200
|
+
* sitePathPrefix: "/blog",
|
|
201
|
+
* languagePrefixes: ["en"],
|
|
202
|
+
* }); // "/about"
|
|
203
|
+
* toInternalPath("https://other.com/about", { siteOrigins: ["https://example.com"] }); // null
|
|
222
204
|
*/
|
|
223
|
-
export function
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
205
|
+
export function toInternalPath(
|
|
206
|
+
input: string,
|
|
207
|
+
options: InternalPathOptions = {},
|
|
208
|
+
): string | null {
|
|
209
|
+
const value = input.trim();
|
|
210
|
+
if (!value) return null;
|
|
211
|
+
|
|
212
|
+
const {
|
|
213
|
+
siteOrigins = [],
|
|
214
|
+
sitePathPrefix = "",
|
|
215
|
+
languagePrefixes = [],
|
|
216
|
+
keepQuery = false,
|
|
217
|
+
} = options;
|
|
218
|
+
|
|
219
|
+
const isFull = isFullUrl(value);
|
|
220
|
+
let candidate: string | null = null;
|
|
221
|
+
if (isFull) {
|
|
222
|
+
for (const origin of siteOrigins) {
|
|
223
|
+
const path = toSameSitePath(value, origin);
|
|
224
|
+
if (path !== null) {
|
|
225
|
+
candidate = path;
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
// A full URL on a host we do not serve is somebody else's page.
|
|
230
|
+
if (candidate === null) return null;
|
|
231
|
+
} else if (
|
|
232
|
+
value.startsWith("//") ||
|
|
233
|
+
ANY_SCHEME_RE.test(value) ||
|
|
234
|
+
value.startsWith("#")
|
|
235
|
+
) {
|
|
236
|
+
return null;
|
|
237
|
+
} else {
|
|
238
|
+
candidate = value;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
let url: URL;
|
|
242
|
+
try {
|
|
243
|
+
// A fixed base resolves `..`, percent-encoding, and stray backslashes the
|
|
244
|
+
// same way the browser that produced the address did.
|
|
245
|
+
url = new URL(candidate, "https://jant.invalid");
|
|
246
|
+
} catch {
|
|
247
|
+
return null;
|
|
228
248
|
}
|
|
229
|
-
|
|
230
|
-
|
|
249
|
+
|
|
250
|
+
const withoutSite = stripSitePathPrefix(
|
|
251
|
+
url.pathname,
|
|
252
|
+
normalizeSitePathPrefix(sitePathPrefix),
|
|
253
|
+
);
|
|
254
|
+
if (withoutSite === null && isFull) {
|
|
255
|
+
// A URL on our host but outside the deployment: another app, not a page.
|
|
256
|
+
return null;
|
|
231
257
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
258
|
+
|
|
259
|
+
// A typed path that does not carry the prefix is already an internal one —
|
|
260
|
+
// an author writing `/about` on a site served from `/blog` means the About
|
|
261
|
+
// page, not a different site.
|
|
262
|
+
const internal = stripLanguagePrefix(
|
|
263
|
+
withoutSite ?? url.pathname,
|
|
264
|
+
languagePrefixes,
|
|
265
|
+
);
|
|
266
|
+
const trimmed =
|
|
267
|
+
internal.length > 1 ? internal.replace(/\/+$/, "") || "/" : internal;
|
|
268
|
+
|
|
269
|
+
return keepQuery ? `${trimmed}${url.search}${url.hash}` : trimmed;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/** Drop a leading `/en`-style segment when the site serves that language. */
|
|
273
|
+
function stripLanguagePrefix(
|
|
274
|
+
pathname: string,
|
|
275
|
+
languagePrefixes: readonly string[],
|
|
276
|
+
): string {
|
|
277
|
+
if (languagePrefixes.length === 0) return pathname;
|
|
278
|
+
|
|
279
|
+
const rest = pathname.startsWith("/") ? pathname.slice(1) : pathname;
|
|
280
|
+
const slash = rest.indexOf("/");
|
|
281
|
+
const first = (slash === -1 ? rest : rest.slice(0, slash)).toLowerCase();
|
|
282
|
+
if (!first) return pathname;
|
|
283
|
+
if (!languagePrefixes.some((prefix) => prefix.toLowerCase() === first)) {
|
|
284
|
+
return pathname;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
return slash === -1 ? "/" : rest.slice(slash);
|
|
235
288
|
}
|
|
236
289
|
|
|
237
290
|
/**
|
package/src/lib/version.ts
CHANGED
|
@@ -1,33 +1,35 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Version and
|
|
3
|
-
*
|
|
4
|
-
* In Vite dev, `__JANT_DEV__` is replaced with `true` via Vite's `define` config.
|
|
5
|
-
* In production (wrangler/esbuild), the typeof check evaluates to false safely.
|
|
2
|
+
* Version and build asset paths
|
|
6
3
|
*
|
|
7
4
|
* `__JANT_VERSION__` is replaced by Vite's `define` during both dev and lib build.
|
|
8
5
|
*
|
|
9
6
|
* `__CLIENT_JS_FILE__` and `__CLIENT_AUTH_JS_FILE__` are content-addressed
|
|
10
7
|
* internal paths (e.g. `/_assets/client-HASH.js`) embedded by the Worker build
|
|
11
8
|
* from the Vite client manifest. Used only in production (IS_VITE_DEV=false).
|
|
9
|
+
* `__CLIENT_COMPOSE_PRELOAD__` lists every file the composer entry needs —
|
|
10
|
+
* the entry and the chunks it imports — for the layout's modulepreload links.
|
|
11
|
+
*
|
|
12
|
+
* The dev flag itself lives in `build-env.ts`, which client bundles can import
|
|
13
|
+
* without these Worker-only globals.
|
|
12
14
|
*/
|
|
13
15
|
|
|
14
|
-
declare const __JANT_DEV__: boolean | undefined;
|
|
15
16
|
declare const __JANT_VERSION__: string;
|
|
16
17
|
declare const __CLIENT_JS_FILE__: string;
|
|
17
18
|
declare const __CLIENT_AUTH_JS_FILE__: string;
|
|
19
|
+
declare const __CLIENT_COMPOSE_PRELOAD__: readonly string[];
|
|
18
20
|
declare const __CLIENT_CSS_FILE__: string;
|
|
21
|
+
declare const __CLIENT_AUTHOR_CSS_FILE__: string;
|
|
19
22
|
declare const __CLIENT_CJK_CSS_FILE__: string;
|
|
20
23
|
declare const __CLIENT_CJK_TC_CSS_FILE__: string;
|
|
21
24
|
declare const __CLIENT_CJK_JP_CSS_FILE__: string;
|
|
22
25
|
declare const __CLIENT_CJK_KR_CSS_FILE__: string;
|
|
23
26
|
|
|
24
|
-
export const IS_VITE_DEV =
|
|
25
|
-
typeof __JANT_DEV__ !== "undefined" && __JANT_DEV__ === true;
|
|
26
|
-
|
|
27
27
|
export const CORE_VERSION = __JANT_VERSION__;
|
|
28
28
|
export const CLIENT_JS_FILE = __CLIENT_JS_FILE__;
|
|
29
29
|
export const CLIENT_AUTH_JS_FILE = __CLIENT_AUTH_JS_FILE__;
|
|
30
|
+
export const CLIENT_COMPOSE_PRELOAD = __CLIENT_COMPOSE_PRELOAD__;
|
|
30
31
|
export const CLIENT_CSS_FILE = __CLIENT_CSS_FILE__;
|
|
32
|
+
export const CLIENT_AUTHOR_CSS_FILE = __CLIENT_AUTHOR_CSS_FILE__;
|
|
31
33
|
export const CLIENT_CJK_CSS_FILE = __CLIENT_CJK_CSS_FILE__;
|
|
32
34
|
export const CLIENT_CJK_TC_CSS_FILE = __CLIENT_CJK_TC_CSS_FILE__;
|
|
33
35
|
export const CLIENT_CJK_JP_CSS_FILE = __CLIENT_CJK_JP_CSS_FILE__;
|