@kernhq/module-quire 0.11.1 → 0.13.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.
Files changed (52) hide show
  1. package/dist/contract/models.d.ts +46 -0
  2. package/dist/contract/models.d.ts.map +1 -1
  3. package/dist/contract/models.js +73 -0
  4. package/dist/contract/models.js.map +1 -1
  5. package/dist/contract/permissions.d.ts +17 -1
  6. package/dist/contract/permissions.d.ts.map +1 -1
  7. package/dist/contract/permissions.js +35 -0
  8. package/dist/contract/permissions.js.map +1 -1
  9. package/dist/contract/router.d.ts +756 -0
  10. package/dist/contract/router.d.ts.map +1 -1
  11. package/dist/contract/router.js +346 -2
  12. package/dist/contract/router.js.map +1 -1
  13. package/dist/server/_impl.d.ts +826 -0
  14. package/dist/server/_impl.d.ts.map +1 -1
  15. package/dist/server/_impl.js +336 -2
  16. package/dist/server/_impl.js.map +1 -1
  17. package/dist/server/schema.d.ts +318 -1
  18. package/dist/server/schema.d.ts.map +1 -1
  19. package/dist/server/schema.js +86 -0
  20. package/dist/server/schema.js.map +1 -1
  21. package/dist/server/services/access.d.ts +1 -0
  22. package/dist/server/services/access.d.ts.map +1 -1
  23. package/dist/server/services/index.d.ts +3 -0
  24. package/dist/server/services/index.d.ts.map +1 -1
  25. package/dist/server/services/index.js +5 -1
  26. package/dist/server/services/index.js.map +1 -1
  27. package/dist/server/services/pages.d.ts.map +1 -1
  28. package/dist/server/services/pages.js +6 -0
  29. package/dist/server/services/pages.js.map +1 -1
  30. package/dist/server/services/publications.d.ts +191 -0
  31. package/dist/server/services/publications.d.ts.map +1 -0
  32. package/dist/server/services/publications.js +772 -0
  33. package/dist/server/services/publications.js.map +1 -0
  34. package/dist/server/services/versions.d.ts +26 -1
  35. package/dist/server/services/versions.d.ts.map +1 -1
  36. package/dist/server/services/versions.js +44 -15
  37. package/dist/server/services/versions.js.map +1 -1
  38. package/migrations/0008_publications.sql +140 -0
  39. package/migrations/0009_public_asset_references.sql +35 -0
  40. package/migrations/meta/_journal.json +14 -0
  41. package/package.json +1 -1
  42. package/src/client/components/PublishDialog.svelte +920 -0
  43. package/src/client/components/SidebarRecents.svelte +17 -1
  44. package/src/client/i18n.ts +448 -0
  45. package/src/client/index.ts +21 -0
  46. package/src/client/mock.ts +436 -2
  47. package/src/client/pages/PageView.svelte +139 -0
  48. package/src/client/public-url.ts +76 -0
  49. package/src/client/query.ts +16 -0
  50. package/src/contract/models.ts +77 -0
  51. package/src/contract/permissions.ts +54 -1
  52. package/src/contract/router.ts +380 -1
@@ -67,7 +67,9 @@ function open(entry: RecentEntry) {
67
67
  A relative time, not a date: this list is only ever read as "how long ago", and
68
68
  `relativeTime` renders it in the interface language rather than as a raw number.
69
69
  -->
70
- <span class="when">{relativeTime(entry.viewedAt)}</span>
70
+ <span class="when" class:on-active={activePageId === entry.pageId}>
71
+ {relativeTime(entry.viewedAt)}
72
+ </span>
71
73
  {/snippet}
72
74
  </SidebarItem>
73
75
  {/each}
@@ -87,6 +89,17 @@ function open(entry: RecentEntry) {
87
89
  /*
88
90
  * Muted with a colour, never with `opacity` — and never smaller than 11.5px, which is where this
89
91
  * pane's ink stops being legible against its own background.
92
+ *
93
+ * **"Its own background" is two backgrounds, and the second one is the row you are standing on.**
94
+ * `SidebarItem` paints an active row `--kern-ink-900` and switches its text to
95
+ * `--kern-ink-inverse`; a timestamp that kept its own muted ink through that landed at **2.83:1 in
96
+ * light and 2.50:1 in dark** — mid-grey on near-black, on the row of the page the reader currently
97
+ * has open, in every locale. Off the active row the same colour is 4.88:1 or better against every
98
+ * ground this pane uses, which is why the token was never the thing that was wrong.
99
+ *
100
+ * So the active row inherits instead of overriding: `--kern-ink-inverse` on `--kern-ink-900` is
101
+ * 16.63:1 light and 15.52:1 dark. Inheriting rather than naming a second colour is also what keeps
102
+ * the two in step if the active row is ever repainted.
90
103
  */
91
104
  .when {
92
105
  flex: none;
@@ -95,4 +108,7 @@ function open(entry: RecentEntry) {
95
108
  color: var(--kern-ink-350);
96
109
  letter-spacing: -0.01em;
97
110
  }
111
+ .when.on-active {
112
+ color: inherit;
113
+ }
98
114
  </style>
@@ -418,6 +418,113 @@ export const en: Record<string, Message> = {
418
418
  one: '{n} person is watching',
419
419
  other: '{n} people are watching',
420
420
  },
421
+
422
+ /*
423
+ * Sharing a page to the web.
424
+ *
425
+ * The one screen in Quire where a misunderstanding is a data leak, so the wording is doing real
426
+ * work rather than labelling controls. Three rules held here and worth keeping:
427
+ *
428
+ * - **Say "without signing in".** "Public" is the word every product uses and half of the people
429
+ * reading it hear "public to my workspace". The sentence has to name the absence of an
430
+ * account, because that is the part that surprises somebody afterwards.
431
+ * - **Name the subtree, every time.** Publishing takes children with it. A sentence about "this
432
+ * page" is true and incomplete, and incomplete is what a leak is made of.
433
+ * - **Nothing here is in the future tense once it is true.** Before the button, "would be
434
+ * public"; after it, "is public". A screen that keeps saying "will be" about something already
435
+ * on the internet is teaching somebody it has not happened yet.
436
+ */
437
+ 'quire.share_web': 'Share to web',
438
+ 'quire.share_title': 'Share to web',
439
+ 'quire.share_warn_title': 'Anyone with the link can read this, without signing in',
440
+ 'quire.share_warn_body':
441
+ 'Publishing puts this page, and every page nested under it, on the public internet. There is no account to make and no invitation to accept: whoever has the address can read it, and so can anyone they pass it to.',
442
+ 'quire.share_warn_version':
443
+ 'Readers are served the last version you published — never the draft you are writing.',
444
+ 'quire.share_warn_unpublished':
445
+ 'A page that has never been published stays private, even when it sits under one that is.',
446
+ 'quire.share_warn_search': 'Search engines are allowed to list it unless you turn that off below.',
447
+ 'quire.share_needs_publish':
448
+ 'This page has no published version yet, so the site would have nothing to show. Publish the page first.',
449
+ 'quire.share_address': 'Address',
450
+ 'quire.share_address_hint': 'Lowercase letters, digits and dashes.',
451
+ 'quire.share_address_invalid': 'Between 2 and 64 lowercase letters, digits or dashes.',
452
+ /*
453
+ * The address is *beside* this sentence, never interpolated into it.
454
+ *
455
+ * A Latin URL dropped into an Arabic or Persian paragraph is laid out by the bidi algorithm
456
+ * against the surrounding direction, and a string full of slashes and dots comes apart — the
457
+ * scheme ends up at the wrong end of the line. Rendering it as its own `dir="ltr"` element is the
458
+ * only way it survives, and a placeholder in the message cannot be one.
459
+ */
460
+ 'quire.share_address_pending':
461
+ 'When you save, the site moves here. The link above is the live one until then.',
462
+ 'quire.share_link': 'Link',
463
+ 'quire.share_copy': 'Copy link',
464
+ 'quire.share_copied': 'Link copied',
465
+ 'quire.share_copy_manually': 'The browser would not copy it. Select the link and copy it by hand.',
466
+ 'quire.share_open': 'Open the published site',
467
+ 'quire.share_include': 'Include the pages nested under this one',
468
+ 'quire.share_include_desc': 'Off publishes this page on its own.',
469
+ 'quire.share_count': {
470
+ one: '{n} page is nested under this one',
471
+ other: '{n} pages are nested under this one',
472
+ },
473
+ 'quire.share_publish': 'Publish to the web',
474
+ 'quire.share_published': 'This page is public',
475
+ 'quire.share_published_when': 'Published {when}',
476
+ 'quire.share_published_toast': 'This page is public. Anyone with the link can read it.',
477
+ 'quire.share_published_empty': 'The site is made, and it has nothing to show',
478
+ 'quire.share_published_empty_toast':
479
+ 'The address works, but this page has never been published, so there is nothing at it yet.',
480
+ 'quire.share_check_running': 'Checking what a signed-out visitor sees…',
481
+ 'quire.share_check_ok': {
482
+ one: 'A signed-out visitor sees {n} page.',
483
+ other: 'A signed-out visitor sees {n} pages.',
484
+ },
485
+ 'quire.share_check_locked': 'A signed-out visitor is asked for the password before anything is shown.',
486
+ 'quire.share_check_failed': 'A signed-out visitor cannot open this address yet.',
487
+ 'quire.share_more': 'More options',
488
+ 'quire.share_less': 'Fewer options',
489
+ 'quire.share_password': 'Password',
490
+ 'quire.share_password_hint':
491
+ 'At least 6 characters. Readers are asked for it before they see anything at all, including the list of pages.',
492
+ 'quire.share_password_keep': 'Leave this empty to keep the password already set.',
493
+ 'quire.share_password_on': 'A password is set',
494
+ 'quire.share_password_remove': 'Remove the password',
495
+ 'quire.share_expires': 'Stop working on',
496
+ 'quire.share_expires_hint': 'The link stops opening after this date. Leave it empty and it never expires.',
497
+ 'quire.share_indexable': 'Let search engines list it',
498
+ 'quire.share_indexable_desc':
499
+ 'Off asks crawlers to leave it out. Public and findable are not the same request.',
500
+ 'quire.share_seo_title': 'Title in search results',
501
+ 'quire.share_seo_title_hint': 'Empty uses the page’s own title.',
502
+ 'quire.share_seo_description': 'Description in search results',
503
+ 'quire.share_og_image': 'Link preview image',
504
+ 'quire.share_og_image_hint': 'Shown when somebody pastes the link into a chat. Paste the image’s address.',
505
+ 'quire.share_theme': 'Theme',
506
+ 'quire.share_theme_auto': 'Follow the reader’s own setting',
507
+ 'quire.share_theme_light': 'Light',
508
+ 'quire.share_theme_dark': 'Dark',
509
+ 'quire.share_children': 'Pages inside this one',
510
+ 'quire.share_children_desc':
511
+ 'Turn one off to keep it, and everything under it, out of every published site — this one and any made later.',
512
+ 'quire.share_children_none': 'Nothing is nested under this page.',
513
+ 'quire.share_children_off': 'Only this page is published, so nothing nested under it is public.',
514
+ 'quire.share_child_private': 'Kept private',
515
+ 'quire.share_child_blocked': 'Under a page that is kept private',
516
+ 'quire.share_child_draft': 'Never published',
517
+ 'quire.share_child_archived': 'Archived',
518
+ 'quire.share_save': 'Save changes',
519
+ 'quire.share_saved': 'Saved',
520
+ 'quire.share_unpublish': 'Unpublish',
521
+ 'quire.share_unpublish_ask':
522
+ 'Take the site down? The link stops working for everybody. Nothing you have written is deleted.',
523
+ 'quire.share_unpublish_done': 'The site has been taken down',
524
+ 'quire.share_done': 'Done',
525
+ 'quire.public_chip': 'Public',
526
+ 'quire.public_chip_root': 'Anyone with the link can read this page and everything under it',
527
+ 'quire.public_chip_child': 'This page is part of a published site anyone can read',
421
528
  }
422
529
 
423
530
  export type QuireMessageKey = keyof typeof en
@@ -864,6 +971,92 @@ const ar: Record<string, Message> = {
864
971
  many: 'يتابعها {n} شخصًا',
865
972
  other: 'يتابعها {n} شخص',
866
973
  },
974
+
975
+ 'quire.share_web': 'النشر على الويب',
976
+ 'quire.share_title': 'النشر على الويب',
977
+ 'quire.share_warn_title': 'كل من يملك الرابط يقرأ هذا دون تسجيل دخول',
978
+ 'quire.share_warn_body':
979
+ 'النشر يضع هذه الصفحة، وكل صفحة تحتها، على الإنترنت العام. لا حساب يُنشأ ولا دعوة تُقبل: من يملك العنوان يقرأ، ومن يعطيه العنوان يقرأ أيضًا.',
980
+ 'quire.share_warn_version': 'يرى القرّاء آخر نسخة نشرتها، لا المسودّة التي تكتبها.',
981
+ 'quire.share_warn_unpublished': 'الصفحة التي لم تُنشر قط تبقى خاصة، حتى لو كانت تحت صفحة منشورة.',
982
+ 'quire.share_warn_search': 'محرّكات البحث مسموح لها بإدراجه ما لم توقف ذلك في الأسفل.',
983
+ 'quire.share_needs_publish':
984
+ 'لا توجد نسخة منشورة من هذه الصفحة بعد، فلن يجد الموقع ما يعرضه. انشر الصفحة أولًا.',
985
+ 'quire.share_address': 'العنوان',
986
+ 'quire.share_address_hint': 'حروف لاتينية صغيرة وأرقام وشرطات.',
987
+ 'quire.share_address_invalid': 'من ٢ إلى ٦٤ حرفًا لاتينيًا صغيرًا أو رقمًا أو شرطة.',
988
+ 'quire.share_address_pending': 'عند الحفظ ينتقل الموقع إلى هنا. الرابط أعلاه هو العامل حتى ذلك الحين.',
989
+ 'quire.share_link': 'الرابط',
990
+ 'quire.share_copy': 'نسخ الرابط',
991
+ 'quire.share_copied': 'نُسخ الرابط',
992
+ 'quire.share_copy_manually': 'المتصفّح رفض النسخ. حدّد الرابط وانسخه بنفسك.',
993
+ 'quire.share_open': 'فتح الموقع المنشور',
994
+ 'quire.share_include': 'ضمّ الصفحات المتفرّعة عن هذه الصفحة',
995
+ 'quire.share_include_desc': 'إيقافه ينشر هذه الصفحة وحدها.',
996
+ 'quire.share_count': {
997
+ zero: 'لا صفحات متفرّعة عن هذه الصفحة',
998
+ one: 'صفحة واحدة متفرّعة عن هذه الصفحة',
999
+ two: 'صفحتان متفرّعتان عن هذه الصفحة',
1000
+ few: '{n} صفحات متفرّعة عن هذه الصفحة',
1001
+ many: '{n} صفحة متفرّعة عن هذه الصفحة',
1002
+ other: '{n} صفحة متفرّعة عن هذه الصفحة',
1003
+ },
1004
+ 'quire.share_publish': 'انشرها على الويب',
1005
+ 'quire.share_published': 'هذه الصفحة عامة',
1006
+ 'quire.share_published_when': 'نُشرت {when}',
1007
+ 'quire.share_published_toast': 'هذه الصفحة عامة الآن. كل من يملك الرابط يقرؤها.',
1008
+ 'quire.share_published_empty': 'أُنشئ الموقع، ولا شيء لديه ليعرضه',
1009
+ 'quire.share_published_empty_toast': 'العنوان يعمل، لكن هذه الصفحة لم تُنشر قط، فلا يوجد عندها شيء بعد.',
1010
+ 'quire.share_check_running': 'جارٍ التحقّق ممّا يراه زائر غير مسجّل…',
1011
+ 'quire.share_check_ok': {
1012
+ zero: 'الزائر غير المسجّل لا يرى أي صفحة.',
1013
+ one: 'الزائر غير المسجّل يرى صفحة واحدة.',
1014
+ two: 'الزائر غير المسجّل يرى صفحتين.',
1015
+ few: 'الزائر غير المسجّل يرى {n} صفحات.',
1016
+ many: 'الزائر غير المسجّل يرى {n} صفحة.',
1017
+ other: 'الزائر غير المسجّل يرى {n} صفحة.',
1018
+ },
1019
+ 'quire.share_check_locked': 'يُطلب من الزائر غير المسجّل كلمة المرور قبل أن يرى أي شيء.',
1020
+ 'quire.share_check_failed': 'الزائر غير المسجّل لا يستطيع فتح هذا العنوان بعد.',
1021
+ 'quire.share_more': 'خيارات أخرى',
1022
+ 'quire.share_less': 'خيارات أقل',
1023
+ 'quire.share_password': 'كلمة المرور',
1024
+ 'quire.share_password_hint':
1025
+ 'ستة محارف على الأقل. تُطلب من القارئ قبل أن يرى أي شيء، بما في ذلك قائمة الصفحات.',
1026
+ 'quire.share_password_keep': 'اتركه فارغًا للإبقاء على كلمة المرور الحالية.',
1027
+ 'quire.share_password_on': 'كلمة المرور مضبوطة',
1028
+ 'quire.share_password_remove': 'إزالة كلمة المرور',
1029
+ 'quire.share_expires': 'يتوقّف في',
1030
+ 'quire.share_expires_hint': 'يتوقّف الرابط عن الفتح بعد هذا التاريخ. اتركه فارغًا فلا ينتهي أبدًا.',
1031
+ 'quire.share_indexable': 'اسمح لمحرّكات البحث بإدراجه',
1032
+ 'quire.share_indexable_desc': 'إيقافه يطلب من الزواحف تجاهله. «عام» و«يمكن العثور عليه» ليسا الطلب نفسه.',
1033
+ 'quire.share_seo_title': 'العنوان في نتائج البحث',
1034
+ 'quire.share_seo_title_hint': 'الفراغ يستخدم عنوان الصفحة نفسها.',
1035
+ 'quire.share_seo_description': 'الوصف في نتائج البحث',
1036
+ 'quire.share_og_image': 'صورة معاينة الرابط',
1037
+ 'quire.share_og_image_hint': 'تظهر حين يلصق أحدهم الرابط في محادثة. الصق عنوان الصورة.',
1038
+ 'quire.share_theme': 'المظهر',
1039
+ 'quire.share_theme_auto': 'اتّباع إعداد القارئ',
1040
+ 'quire.share_theme_light': 'فاتح',
1041
+ 'quire.share_theme_dark': 'داكن',
1042
+ 'quire.share_children': 'الصفحات داخل هذه الصفحة',
1043
+ 'quire.share_children_desc':
1044
+ 'أوقف واحدة لتبقى هي وكل ما تحتها خارج أي موقع منشور: هذا الموقع وما يُنشأ لاحقًا.',
1045
+ 'quire.share_children_none': 'لا شيء متفرّع عن هذه الصفحة.',
1046
+ 'quire.share_children_off': 'هذه الصفحة وحدها منشورة، فلا شيء متفرّع عنها عام.',
1047
+ 'quire.share_child_private': 'محفوظة خاصة',
1048
+ 'quire.share_child_blocked': 'تحت صفحة محفوظة خاصة',
1049
+ 'quire.share_child_draft': 'لم تُنشر قط',
1050
+ 'quire.share_child_archived': 'مؤرشفة',
1051
+ 'quire.share_save': 'حفظ التغييرات',
1052
+ 'quire.share_saved': 'حُفظ',
1053
+ 'quire.share_unpublish': 'إلغاء النشر',
1054
+ 'quire.share_unpublish_ask': 'هل تُنزل الموقع؟ يتوقّف الرابط عن العمل للجميع. لا يُحذف شيء ممّا كتبته.',
1055
+ 'quire.share_unpublish_done': 'أُنزل الموقع',
1056
+ 'quire.share_done': 'تمّ',
1057
+ 'quire.public_chip': 'عام',
1058
+ 'quire.public_chip_root': 'كل من يملك الرابط يقرأ هذه الصفحة وكل ما تحتها',
1059
+ 'quire.public_chip_child': 'هذه الصفحة جزء من موقع منشور يقرؤه الجميع',
867
1060
  }
868
1061
 
869
1062
  const de: Record<string, Message> = {
@@ -1279,6 +1472,94 @@ const de: Record<string, Message> = {
1279
1472
  one: '{n} Person beobachtet die Seite',
1280
1473
  other: '{n} Personen beobachten die Seite',
1281
1474
  },
1475
+
1476
+ 'quire.share_web': 'Im Web veröffentlichen',
1477
+ 'quire.share_title': 'Im Web veröffentlichen',
1478
+ 'quire.share_warn_title': 'Wer den Link hat, kann das ohne Anmeldung lesen',
1479
+ 'quire.share_warn_body':
1480
+ 'Veröffentlichen stellt diese Seite und jede darunter liegende Seite ins öffentliche Internet. Kein Konto, keine Einladung: Wer die Adresse hat, liest mit — und wer sie von dort bekommt, ebenso.',
1481
+ 'quire.share_warn_version':
1482
+ 'Lesende bekommen die zuletzt veröffentlichte Fassung, nie den Entwurf, an dem du schreibst.',
1483
+ 'quire.share_warn_unpublished':
1484
+ 'Eine nie veröffentlichte Seite bleibt privat, auch wenn sie unter einer veröffentlichten liegt.',
1485
+ 'quire.share_warn_search': 'Suchmaschinen dürfen die Seite listen, solange du das unten nicht abschaltest.',
1486
+ 'quire.share_needs_publish':
1487
+ 'Diese Seite hat noch keine veröffentlichte Fassung, die Website hätte also nichts zu zeigen. Veröffentliche zuerst die Seite.',
1488
+ 'quire.share_address': 'Adresse',
1489
+ 'quire.share_address_hint': 'Kleinbuchstaben, Ziffern und Bindestriche.',
1490
+ 'quire.share_address_invalid': '2 bis 64 Kleinbuchstaben, Ziffern oder Bindestriche.',
1491
+ 'quire.share_address_pending':
1492
+ 'Beim Speichern zieht die Website hierher um. Bis dahin ist der Link oben der aktive.',
1493
+ 'quire.share_link': 'Link',
1494
+ 'quire.share_copy': 'Link kopieren',
1495
+ 'quire.share_copied': 'Link kopiert',
1496
+ 'quire.share_copy_manually':
1497
+ 'Der Browser hat das Kopieren abgelehnt. Markiere den Link und kopiere ihn selbst.',
1498
+ 'quire.share_open': 'Veröffentlichte Website öffnen',
1499
+ 'quire.share_include': 'Die darunter liegenden Seiten mitveröffentlichen',
1500
+ 'quire.share_include_desc': 'Aus veröffentlicht nur diese eine Seite.',
1501
+ 'quire.share_count': {
1502
+ one: '{n} Seite liegt unter dieser',
1503
+ other: '{n} Seiten liegen unter dieser',
1504
+ },
1505
+ 'quire.share_publish': 'Im Web veröffentlichen',
1506
+ 'quire.share_published': 'Diese Seite ist öffentlich',
1507
+ 'quire.share_published_when': 'Veröffentlicht {when}',
1508
+ 'quire.share_published_toast': 'Diese Seite ist öffentlich. Wer den Link hat, kann sie lesen.',
1509
+ 'quire.share_published_empty': 'Die Website steht, und sie hat nichts zu zeigen',
1510
+ 'quire.share_published_empty_toast':
1511
+ 'Die Adresse funktioniert, aber diese Seite wurde nie veröffentlicht — dort ist also noch nichts.',
1512
+ 'quire.share_check_running': 'Wird geprüft, was ein abgemeldeter Besuch sieht …',
1513
+ 'quire.share_check_ok': {
1514
+ one: 'Ein abgemeldeter Besuch sieht {n} Seite.',
1515
+ other: 'Ein abgemeldeter Besuch sieht {n} Seiten.',
1516
+ },
1517
+ 'quire.share_check_locked':
1518
+ 'Ein abgemeldeter Besuch wird nach dem Passwort gefragt, bevor irgendetwas zu sehen ist.',
1519
+ 'quire.share_check_failed': 'Ein abgemeldeter Besuch kann diese Adresse noch nicht öffnen.',
1520
+ 'quire.share_more': 'Mehr Einstellungen',
1521
+ 'quire.share_less': 'Weniger Einstellungen',
1522
+ 'quire.share_password': 'Passwort',
1523
+ 'quire.share_password_hint':
1524
+ 'Mindestens 6 Zeichen. Lesende werden danach gefragt, bevor sie irgendetwas sehen — auch die Seitenliste.',
1525
+ 'quire.share_password_keep': 'Leer lassen, um das bisherige Passwort zu behalten.',
1526
+ 'quire.share_password_on': 'Ein Passwort ist gesetzt',
1527
+ 'quire.share_password_remove': 'Passwort entfernen',
1528
+ 'quire.share_expires': 'Läuft ab am',
1529
+ 'quire.share_expires_hint':
1530
+ 'Nach diesem Datum öffnet der Link nicht mehr. Leer lassen, und er läuft nie ab.',
1531
+ 'quire.share_indexable': 'Von Suchmaschinen listen lassen',
1532
+ 'quire.share_indexable_desc':
1533
+ 'Aus bittet Crawler, sie auszulassen. Öffentlich und auffindbar sind zwei verschiedene Wünsche.',
1534
+ 'quire.share_seo_title': 'Titel in Suchergebnissen',
1535
+ 'quire.share_seo_title_hint': 'Leer nimmt den Titel der Seite selbst.',
1536
+ 'quire.share_seo_description': 'Beschreibung in Suchergebnissen',
1537
+ 'quire.share_og_image': 'Vorschaubild des Links',
1538
+ 'quire.share_og_image_hint':
1539
+ 'Wird gezeigt, wenn jemand den Link in einen Chat einfügt. Adresse des Bildes einfügen.',
1540
+ 'quire.share_theme': 'Erscheinungsbild',
1541
+ 'quire.share_theme_auto': 'Der Einstellung der Lesenden folgen',
1542
+ 'quire.share_theme_light': 'Hell',
1543
+ 'quire.share_theme_dark': 'Dunkel',
1544
+ 'quire.share_children': 'Seiten unter dieser',
1545
+ 'quire.share_children_desc':
1546
+ 'Schalte eine ab, damit sie — und alles darunter — aus jeder veröffentlichten Website herausbleibt: aus dieser und aus später angelegten.',
1547
+ 'quire.share_children_none': 'Unter dieser Seite liegt nichts.',
1548
+ 'quire.share_children_off': 'Nur diese Seite ist veröffentlicht, alles darunter bleibt privat.',
1549
+ 'quire.share_child_private': 'Bleibt privat',
1550
+ 'quire.share_child_blocked': 'Unter einer Seite, die privat bleibt',
1551
+ 'quire.share_child_draft': 'Nie veröffentlicht',
1552
+ 'quire.share_child_archived': 'Archiviert',
1553
+ 'quire.share_save': 'Änderungen speichern',
1554
+ 'quire.share_saved': 'Gespeichert',
1555
+ 'quire.share_unpublish': 'Veröffentlichung beenden',
1556
+ 'quire.share_unpublish_ask':
1557
+ 'Die Website abschalten? Der Link funktioniert dann für niemanden mehr. Nichts von dem, was du geschrieben hast, wird gelöscht.',
1558
+ 'quire.share_unpublish_done': 'Die Website ist abgeschaltet',
1559
+ 'quire.share_done': 'Fertig',
1560
+ 'quire.public_chip': 'Öffentlich',
1561
+ 'quire.public_chip_root': 'Wer den Link hat, kann diese Seite und alles darunter lesen',
1562
+ 'quire.public_chip_child': 'Diese Seite gehört zu einer veröffentlichten Website, die jeder lesen kann',
1282
1563
  }
1283
1564
 
1284
1565
  const fa: Record<string, Message> = {
@@ -1682,6 +1963,88 @@ const fa: Record<string, Message> = {
1682
1963
  one: '{n} نفر دنبال می‌کند',
1683
1964
  other: '{n} نفر دنبال می‌کنند',
1684
1965
  },
1966
+
1967
+ 'quire.share_web': 'انتشار روی وب',
1968
+ 'quire.share_title': 'انتشار روی وب',
1969
+ 'quire.share_warn_title': 'هر کس پیوند را داشته باشد، بدون ورود این را می‌خواند',
1970
+ 'quire.share_warn_body':
1971
+ 'انتشار، این صفحه و هر صفحهٔ زیر آن را روی اینترنت عمومی می‌گذارد. نه حسابی ساخته می‌شود و نه دعوتی پذیرفته: هر کس نشانی را داشته باشد می‌خواند و هر کس نشانی را از او بگیرد هم می‌خواند.',
1972
+ 'quire.share_warn_version':
1973
+ 'خواننده آخرین نسخه‌ای را می‌بیند که منتشر کرده‌اید، نه پیش‌نویسی که در حال نوشتنش هستید.',
1974
+ 'quire.share_warn_unpublished': 'صفحه‌ای که هرگز منتشر نشده خصوصی می‌ماند، حتی اگر زیر صفحه‌ای منتشرشده باشد.',
1975
+ 'quire.share_warn_search': 'موتورهای جست‌وجو اجازه دارند آن را فهرست کنند، مگر پایین‌تر این را خاموش کنید.',
1976
+ 'quire.share_needs_publish':
1977
+ 'این صفحه هنوز نسخهٔ منتشرشده‌ای ندارد، پس سایت چیزی برای نشان‌دادن نخواهد داشت. نخست صفحه را منتشر کنید.',
1978
+ 'quire.share_address': 'نشانی',
1979
+ 'quire.share_address_hint': 'حروف کوچک لاتین، رقم و خط تیره.',
1980
+ 'quire.share_address_invalid': 'بین ۲ تا ۶۴ حرف کوچک لاتین، رقم یا خط تیره.',
1981
+ 'quire.share_address_pending': 'با ذخیره، سایت به اینجا می‌رود. تا آن وقت پیوند بالا همان پیوند زنده است.',
1982
+ 'quire.share_link': 'پیوند',
1983
+ 'quire.share_copy': 'رونوشت پیوند',
1984
+ 'quire.share_copied': 'پیوند رونوشت شد',
1985
+ 'quire.share_copy_manually': 'مرورگر رونوشت را انجام نداد. پیوند را انتخاب و خودتان رونوشت کنید.',
1986
+ 'quire.share_open': 'گشودن سایت منتشرشده',
1987
+ 'quire.share_include': 'صفحه‌های زیر این صفحه هم منتشر شوند',
1988
+ 'quire.share_include_desc': 'خاموش، تنها همین یک صفحه را منتشر می‌کند.',
1989
+ 'quire.share_count': {
1990
+ one: '{n} صفحه زیر این صفحه است',
1991
+ other: '{n} صفحه زیر این صفحه است',
1992
+ },
1993
+ 'quire.share_publish': 'انتشار روی وب',
1994
+ 'quire.share_published': 'این صفحه عمومی است',
1995
+ 'quire.share_published_when': '{when} منتشر شد',
1996
+ 'quire.share_published_toast': 'این صفحه عمومی شد. هر کس پیوند را داشته باشد می‌خواند.',
1997
+ 'quire.share_published_empty': 'سایت ساخته شد و چیزی برای نشان‌دادن ندارد',
1998
+ 'quire.share_published_empty_toast':
1999
+ 'نشانی کار می‌کند، اما این صفحه هرگز منتشر نشده است، پس هنوز چیزی در آن نیست.',
2000
+ 'quire.share_check_running': 'بررسی آنچه بازدیدکنندهٔ واردنشده می‌بیند…',
2001
+ 'quire.share_check_ok': {
2002
+ one: 'بازدیدکنندهٔ واردنشده {n} صفحه می‌بیند.',
2003
+ other: 'بازدیدکنندهٔ واردنشده {n} صفحه می‌بیند.',
2004
+ },
2005
+ 'quire.share_check_locked': 'پیش از آنکه چیزی نشان داده شود، از بازدیدکنندهٔ واردنشده گذرواژه خواسته می‌شود.',
2006
+ 'quire.share_check_failed': 'بازدیدکنندهٔ واردنشده هنوز نمی‌تواند این نشانی را باز کند.',
2007
+ 'quire.share_more': 'گزینه‌های بیشتر',
2008
+ 'quire.share_less': 'گزینه‌های کمتر',
2009
+ 'quire.share_password': 'گذرواژه',
2010
+ 'quire.share_password_hint':
2011
+ 'دست‌کم ۶ نویسه. پیش از آنکه خواننده چیزی ببیند — حتی فهرست صفحه‌ها — از او خواسته می‌شود.',
2012
+ 'quire.share_password_keep': 'برای نگه‌داشتن گذرواژهٔ کنونی، خالی بگذارید.',
2013
+ 'quire.share_password_on': 'گذرواژه تنظیم شده است',
2014
+ 'quire.share_password_remove': 'برداشتن گذرواژه',
2015
+ 'quire.share_expires': 'پایان کار در',
2016
+ 'quire.share_expires_hint': 'پس از این تاریخ پیوند باز نمی‌شود. خالی بگذارید تا هرگز منقضی نشود.',
2017
+ 'quire.share_indexable': 'موتورهای جست‌وجو آن را فهرست کنند',
2018
+ 'quire.share_indexable_desc':
2019
+ 'خاموش، از خزنده‌ها می‌خواهد کنارش بگذارند. «عمومی» و «یافتنی» دو خواستهٔ جدا هستند.',
2020
+ 'quire.share_seo_title': 'عنوان در نتایج جست‌وجو',
2021
+ 'quire.share_seo_title_hint': 'خالی، عنوان خودِ صفحه را می‌گیرد.',
2022
+ 'quire.share_seo_description': 'توضیح در نتایج جست‌وجو',
2023
+ 'quire.share_og_image': 'تصویر پیش‌نمایش پیوند',
2024
+ 'quire.share_og_image_hint': 'وقتی کسی پیوند را در گفت‌وگویی می‌چسباند دیده می‌شود. نشانی تصویر را بچسبانید.',
2025
+ 'quire.share_theme': 'پوسته',
2026
+ 'quire.share_theme_auto': 'پیروی از تنظیم خودِ خواننده',
2027
+ 'quire.share_theme_light': 'روشن',
2028
+ 'quire.share_theme_dark': 'تیره',
2029
+ 'quire.share_children': 'صفحه‌های درون این صفحه',
2030
+ 'quire.share_children_desc':
2031
+ 'یکی را خاموش کنید تا خودش و هر چه زیر اوست از هر سایت منتشرشده بیرون بماند: همین یکی و هر چه بعدها ساخته شود.',
2032
+ 'quire.share_children_none': 'چیزی زیر این صفحه نیست.',
2033
+ 'quire.share_children_off': 'تنها همین صفحه منتشر شده است، پس چیزی زیر آن عمومی نیست.',
2034
+ 'quire.share_child_private': 'خصوصی می‌ماند',
2035
+ 'quire.share_child_blocked': 'زیر صفحه‌ای که خصوصی مانده است',
2036
+ 'quire.share_child_draft': 'هرگز منتشر نشده',
2037
+ 'quire.share_child_archived': 'بایگانی‌شده',
2038
+ 'quire.share_save': 'ذخیرهٔ تغییرها',
2039
+ 'quire.share_saved': 'ذخیره شد',
2040
+ 'quire.share_unpublish': 'پایان انتشار',
2041
+ 'quire.share_unpublish_ask':
2042
+ 'سایت پایین آورده شود؟ پیوند برای همه از کار می‌افتد. چیزی از آنچه نوشته‌اید حذف نمی‌شود.',
2043
+ 'quire.share_unpublish_done': 'سایت پایین آورده شد',
2044
+ 'quire.share_done': 'تمام',
2045
+ 'quire.public_chip': 'عمومی',
2046
+ 'quire.public_chip_root': 'هر کس پیوند را داشته باشد این صفحه و هر چه زیر آن است را می‌خواند',
2047
+ 'quire.public_chip_child': 'این صفحه بخشی از سایتی منتشرشده است که همه می‌خوانند',
1685
2048
  }
1686
2049
 
1687
2050
  const tr: Record<string, Message> = {
@@ -2088,6 +2451,91 @@ const tr: Record<string, Message> = {
2088
2451
  one: '{n} kişi izliyor',
2089
2452
  other: '{n} kişi izliyor',
2090
2453
  },
2454
+
2455
+ 'quire.share_web': 'Web’de yayımla',
2456
+ 'quire.share_title': 'Web’de yayımla',
2457
+ 'quire.share_warn_title': 'Bağlantıya sahip olan herkes, oturum açmadan okuyabilir',
2458
+ 'quire.share_warn_body':
2459
+ 'Yayımlamak bu sayfayı ve altındaki her sayfayı açık internete koyar. Hesap açmak da davet kabul etmek de gerekmez: adresi olan okur, adresi ondan alan da okur.',
2460
+ 'quire.share_warn_version':
2461
+ 'Okuyanlara yayımladığınız son sürüm gösterilir, yazmakta olduğunuz taslak değil.',
2462
+ 'quire.share_warn_unpublished':
2463
+ 'Hiç yayımlanmamış bir sayfa, yayımlanmış bir sayfanın altında olsa bile özel kalır.',
2464
+ 'quire.share_warn_search': 'Aşağıdan kapatmazsanız arama motorları listeleyebilir.',
2465
+ 'quire.share_needs_publish':
2466
+ 'Bu sayfanın henüz yayımlanmış bir sürümü yok, dolayısıyla sitenin gösterecek bir şeyi olmaz. Önce sayfayı yayımlayın.',
2467
+ 'quire.share_address': 'Adres',
2468
+ 'quire.share_address_hint': 'Küçük harf, rakam ve tire.',
2469
+ 'quire.share_address_invalid': '2 ile 64 arasında küçük harf, rakam veya tire.',
2470
+ 'quire.share_address_pending':
2471
+ 'Kaydettiğinizde site buraya taşınır. O ana kadar canlı bağlantı yukarıdakidir.',
2472
+ 'quire.share_link': 'Bağlantı',
2473
+ 'quire.share_copy': 'Bağlantıyı kopyala',
2474
+ 'quire.share_copied': 'Bağlantı kopyalandı',
2475
+ 'quire.share_copy_manually': 'Tarayıcı kopyalamadı. Bağlantıyı seçip elle kopyalayın.',
2476
+ 'quire.share_open': 'Yayımlanan siteyi aç',
2477
+ 'quire.share_include': 'Bu sayfanın altındaki sayfaları da yayımla',
2478
+ 'quire.share_include_desc': 'Kapalıyken yalnızca bu sayfa yayımlanır.',
2479
+ 'quire.share_count': {
2480
+ one: 'Bu sayfanın altında {n} sayfa var',
2481
+ other: 'Bu sayfanın altında {n} sayfa var',
2482
+ },
2483
+ 'quire.share_publish': 'Web’de yayımla',
2484
+ 'quire.share_published': 'Bu sayfa herkese açık',
2485
+ 'quire.share_published_when': '{when} yayımlandı',
2486
+ 'quire.share_published_toast': 'Bu sayfa herkese açık. Bağlantısı olan herkes okuyabilir.',
2487
+ 'quire.share_published_empty': 'Site kuruldu ve gösterecek bir şeyi yok',
2488
+ 'quire.share_published_empty_toast':
2489
+ 'Adres çalışıyor, ama bu sayfa hiç yayımlanmadı; dolayısıyla orada henüz bir şey yok.',
2490
+ 'quire.share_check_running': 'Oturum açmamış bir ziyaretçinin ne gördüğü denetleniyor…',
2491
+ 'quire.share_check_ok': {
2492
+ one: 'Oturum açmamış bir ziyaretçi {n} sayfa görüyor.',
2493
+ other: 'Oturum açmamış bir ziyaretçi {n} sayfa görüyor.',
2494
+ },
2495
+ 'quire.share_check_locked': 'Oturum açmamış bir ziyaretçiye hiçbir şey gösterilmeden önce parola sorulur.',
2496
+ 'quire.share_check_failed': 'Oturum açmamış bir ziyaretçi bu adresi henüz açamıyor.',
2497
+ 'quire.share_more': 'Daha fazla seçenek',
2498
+ 'quire.share_less': 'Daha az seçenek',
2499
+ 'quire.share_password': 'Parola',
2500
+ 'quire.share_password_hint':
2501
+ 'En az 6 karakter. Okuyana, sayfa listesi dâhil hiçbir şey gösterilmeden önce sorulur.',
2502
+ 'quire.share_password_keep': 'Mevcut parolayı korumak için boş bırakın.',
2503
+ 'quire.share_password_on': 'Bir parola tanımlı',
2504
+ 'quire.share_password_remove': 'Parolayı kaldır',
2505
+ 'quire.share_expires': 'Şu tarihte kapansın',
2506
+ 'quire.share_expires_hint': 'Bu tarihten sonra bağlantı açılmaz. Boş bırakırsanız hiç sona ermez.',
2507
+ 'quire.share_indexable': 'Arama motorları listeleyebilsin',
2508
+ 'quire.share_indexable_desc':
2509
+ 'Kapalıyken tarayıcı botlarından atlamaları istenir. Herkese açık olmak ile bulunabilir olmak aynı istek değildir.',
2510
+ 'quire.share_seo_title': 'Arama sonuçlarındaki başlık',
2511
+ 'quire.share_seo_title_hint': 'Boş bırakılırsa sayfanın kendi başlığı kullanılır.',
2512
+ 'quire.share_seo_description': 'Arama sonuçlarındaki açıklama',
2513
+ 'quire.share_og_image': 'Bağlantı önizleme görseli',
2514
+ 'quire.share_og_image_hint':
2515
+ 'Bağlantı bir sohbete yapıştırıldığında görünür. Görselin adresini yapıştırın.',
2516
+ 'quire.share_theme': 'Görünüm',
2517
+ 'quire.share_theme_auto': 'Okuyanın kendi ayarına uy',
2518
+ 'quire.share_theme_light': 'Açık',
2519
+ 'quire.share_theme_dark': 'Koyu',
2520
+ 'quire.share_children': 'Bu sayfanın içindeki sayfalar',
2521
+ 'quire.share_children_desc':
2522
+ 'Birini kapatınca o sayfa ve altındaki her şey, bu site de sonra kurulacaklar da dâhil hiçbir yayımlanmış siteye girmez.',
2523
+ 'quire.share_children_none': 'Bu sayfanın altında bir şey yok.',
2524
+ 'quire.share_children_off': 'Yalnızca bu sayfa yayımlandı, altındaki hiçbir şey herkese açık değil.',
2525
+ 'quire.share_child_private': 'Özel kalıyor',
2526
+ 'quire.share_child_blocked': 'Özel kalan bir sayfanın altında',
2527
+ 'quire.share_child_draft': 'Hiç yayımlanmadı',
2528
+ 'quire.share_child_archived': 'Arşivlendi',
2529
+ 'quire.share_save': 'Değişiklikleri kaydet',
2530
+ 'quire.share_saved': 'Kaydedildi',
2531
+ 'quire.share_unpublish': 'Yayımdan kaldır',
2532
+ 'quire.share_unpublish_ask':
2533
+ 'Site kapatılsın mı? Bağlantı herkes için çalışmaz olur. Yazdıklarınızdan hiçbiri silinmez.',
2534
+ 'quire.share_unpublish_done': 'Site kapatıldı',
2535
+ 'quire.share_done': 'Tamam',
2536
+ 'quire.public_chip': 'Herkese açık',
2537
+ 'quire.public_chip_root': 'Bağlantısı olan herkes bu sayfayı ve altındaki her şeyi okuyabilir',
2538
+ 'quire.public_chip_child': 'Bu sayfa, herkesin okuyabildiği yayımlanmış bir sitenin parçası',
2091
2539
  }
2092
2540
 
2093
2541
  /** In the shape `defineClientModule().messages` expects. */
@@ -36,6 +36,14 @@ export {
36
36
  type PageKind,
37
37
  type PageNode,
38
38
  type PageVersion,
39
+ type Publication,
40
+ type PublicationTheme,
41
+ type PublicBreadcrumb,
42
+ type PublicNavEntry,
43
+ type PublicPage,
44
+ type PublicSearchHit,
45
+ type PublicSite,
46
+ type PublicSiteDetail,
39
47
  quirePermissions,
40
48
  type RecentEntry,
41
49
  type RecentView,
@@ -120,3 +128,16 @@ export { __setQuireApi, getQuireApi } from './api-instance.js'
120
128
  export { type QuireMessageKey, quireMessageBundles, t } from './i18n.js'
121
129
  export { quireClientModule, quireClientModule as default } from './module.js'
122
130
  export { canQuire, QUIRE_PERMISSIONS, type QuirePermission } from './permissions.js'
131
+ /**
132
+ * Where a published site lives.
133
+ *
134
+ * Exported for the same reason `pageDocumentName` above is: the module owns the naming of its own
135
+ * objects, and this is the only definition of a publication's address. Whatever ends up rendering a
136
+ * published page reads it from here rather than writing the prefix out again.
137
+ */
138
+ export {
139
+ PUBLIC_SITE_PREFIX,
140
+ type PublicSiteAddress,
141
+ publicSiteBasePath,
142
+ publicSiteUrl,
143
+ } from './public-url.js'