@geekity/cms 0.17.0 → 0.18.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 (250) hide show
  1. package/README.md +162 -50
  2. package/admin/pages/documents/editor.njk +63 -0
  3. package/admin/pages/documents/list.njk +2 -0
  4. package/admin/pages/indieauth/consent.njk +4 -0
  5. package/admin/pages/settings/privacy.njk +37 -0
  6. package/admin/pages/users/apps.njk +109 -3
  7. package/dist/admin/documents.d.ts +29 -1
  8. package/dist/admin/documents.d.ts.map +1 -1
  9. package/dist/admin/documents.js +88 -6
  10. package/dist/admin/documents.js.map +1 -1
  11. package/dist/admin/index.d.ts +1 -0
  12. package/dist/admin/index.d.ts.map +1 -1
  13. package/dist/admin/index.js +1 -0
  14. package/dist/admin/index.js.map +1 -1
  15. package/dist/admin/location-field.d.ts +26 -0
  16. package/dist/admin/location-field.d.ts.map +1 -0
  17. package/dist/admin/location-field.js +90 -0
  18. package/dist/admin/location-field.js.map +1 -0
  19. package/dist/admin/menu.d.ts.map +1 -1
  20. package/dist/admin/menu.js +1 -0
  21. package/dist/admin/menu.js.map +1 -1
  22. package/dist/admin/preview.d.ts.map +1 -1
  23. package/dist/admin/preview.js +18 -5
  24. package/dist/admin/preview.js.map +1 -1
  25. package/dist/admin/read-field.d.ts +23 -0
  26. package/dist/admin/read-field.d.ts.map +1 -0
  27. package/dist/admin/read-field.js +53 -0
  28. package/dist/admin/read-field.js.map +1 -0
  29. package/dist/admin/settings-page.d.ts +3 -3
  30. package/dist/admin/settings-page.js +2 -2
  31. package/dist/admin/settings-pages.d.ts +2 -2
  32. package/dist/admin/settings-pages.d.ts.map +1 -1
  33. package/dist/admin/settings-pages.js +4 -2
  34. package/dist/admin/settings-pages.js.map +1 -1
  35. package/dist/admin/settings-privacy.d.ts +3 -0
  36. package/dist/admin/settings-privacy.d.ts.map +1 -0
  37. package/dist/admin/settings-privacy.js +10 -0
  38. package/dist/admin/settings-privacy.js.map +1 -0
  39. package/dist/admin/settings-reading.js +2 -2
  40. package/dist/admin/settings-reading.js.map +1 -1
  41. package/dist/admin/settings.d.ts +18 -2
  42. package/dist/admin/settings.d.ts.map +1 -1
  43. package/dist/admin/settings.js +27 -0
  44. package/dist/admin/settings.js.map +1 -1
  45. package/dist/admin/templates.d.ts +1 -0
  46. package/dist/admin/templates.d.ts.map +1 -1
  47. package/dist/admin/templates.js +1 -0
  48. package/dist/admin/templates.js.map +1 -1
  49. package/dist/admin/uploads.d.ts.map +1 -1
  50. package/dist/admin/uploads.js +14 -1
  51. package/dist/admin/uploads.js.map +1 -1
  52. package/dist/cli.d.ts +1 -1
  53. package/dist/cli.d.ts.map +1 -1
  54. package/dist/cli.js +34 -0
  55. package/dist/cli.js.map +1 -1
  56. package/dist/comments/routes.js +2 -2
  57. package/dist/comments/routes.js.map +1 -1
  58. package/dist/contact/routes.js +2 -2
  59. package/dist/contact/routes.js.map +1 -1
  60. package/dist/content/location.d.ts +58 -0
  61. package/dist/content/location.d.ts.map +1 -0
  62. package/dist/content/location.js +208 -0
  63. package/dist/content/location.js.map +1 -0
  64. package/dist/content/locations.d.ts +9 -0
  65. package/dist/content/locations.d.ts.map +1 -0
  66. package/dist/content/locations.js +82 -0
  67. package/dist/content/locations.js.map +1 -0
  68. package/dist/content/metadata/gif.d.ts +3 -0
  69. package/dist/content/metadata/gif.d.ts.map +1 -0
  70. package/dist/content/metadata/gif.js +65 -0
  71. package/dist/content/metadata/gif.js.map +1 -0
  72. package/dist/content/metadata/index.d.ts +6 -0
  73. package/dist/content/metadata/index.d.ts.map +1 -0
  74. package/dist/content/metadata/index.js +24 -0
  75. package/dist/content/metadata/index.js.map +1 -0
  76. package/dist/content/metadata/isobmff.d.ts +22 -0
  77. package/dist/content/metadata/isobmff.d.ts.map +1 -0
  78. package/dist/content/metadata/isobmff.js +215 -0
  79. package/dist/content/metadata/isobmff.js.map +1 -0
  80. package/dist/content/metadata/jpeg.d.ts +3 -0
  81. package/dist/content/metadata/jpeg.d.ts.map +1 -0
  82. package/dist/content/metadata/jpeg.js +117 -0
  83. package/dist/content/metadata/jpeg.js.map +1 -0
  84. package/dist/content/metadata/png.d.ts +3 -0
  85. package/dist/content/metadata/png.d.ts.map +1 -0
  86. package/dist/content/metadata/png.js +74 -0
  87. package/dist/content/metadata/png.js.map +1 -0
  88. package/dist/content/metadata/shared.d.ts +17 -0
  89. package/dist/content/metadata/shared.d.ts.map +1 -0
  90. package/dist/content/metadata/shared.js +42 -0
  91. package/dist/content/metadata/shared.js.map +1 -0
  92. package/dist/content/metadata/sweep.d.ts +14 -0
  93. package/dist/content/metadata/sweep.d.ts.map +1 -0
  94. package/dist/content/metadata/sweep.js +54 -0
  95. package/dist/content/metadata/sweep.js.map +1 -0
  96. package/dist/content/metadata/tiff.d.ts +7 -0
  97. package/dist/content/metadata/tiff.d.ts.map +1 -0
  98. package/dist/content/metadata/tiff.js +56 -0
  99. package/dist/content/metadata/tiff.js.map +1 -0
  100. package/dist/content/metadata/webp.d.ts +3 -0
  101. package/dist/content/metadata/webp.d.ts.map +1 -0
  102. package/dist/content/metadata/webp.js +67 -0
  103. package/dist/content/metadata/webp.js.map +1 -0
  104. package/dist/content/post-type.d.ts +4 -2
  105. package/dist/content/post-type.d.ts.map +1 -1
  106. package/dist/content/post-type.js +9 -1
  107. package/dist/content/post-type.js.map +1 -1
  108. package/dist/content/read.d.ts +22 -0
  109. package/dist/content/read.d.ts.map +1 -0
  110. package/dist/content/read.js +67 -0
  111. package/dist/content/read.js.map +1 -0
  112. package/dist/content/store.d.ts +4 -4
  113. package/dist/content/store.d.ts.map +1 -1
  114. package/dist/content/store.js +19 -39
  115. package/dist/content/store.js.map +1 -1
  116. package/dist/content/sync.d.ts.map +1 -1
  117. package/dist/content/sync.js +3 -13
  118. package/dist/content/sync.js.map +1 -1
  119. package/dist/content/visibility.d.ts +11 -0
  120. package/dist/content/visibility.d.ts.map +1 -0
  121. package/dist/content/visibility.js +14 -0
  122. package/dist/content/visibility.js.map +1 -0
  123. package/dist/federation/article.d.ts.map +1 -1
  124. package/dist/federation/article.js +41 -14
  125. package/dist/federation/article.js.map +1 -1
  126. package/dist/federation/delivery.d.ts +3 -1
  127. package/dist/federation/delivery.d.ts.map +1 -1
  128. package/dist/federation/delivery.js +6 -5
  129. package/dist/federation/delivery.js.map +1 -1
  130. package/dist/federation/mount.d.ts.map +1 -1
  131. package/dist/federation/mount.js +3 -1
  132. package/dist/federation/mount.js.map +1 -1
  133. package/dist/index.d.ts +1 -1
  134. package/dist/index.d.ts.map +1 -1
  135. package/dist/index.js +5 -1
  136. package/dist/index.js.map +1 -1
  137. package/dist/indexnow.js +2 -2
  138. package/dist/indexnow.js.map +1 -1
  139. package/dist/indieauth/activity-log.d.ts +2 -0
  140. package/dist/indieauth/activity-log.d.ts.map +1 -1
  141. package/dist/indieauth/activity-log.js +12 -2
  142. package/dist/indieauth/activity-log.js.map +1 -1
  143. package/dist/indieauth/app-activity.js +5 -1
  144. package/dist/indieauth/app-activity.js.map +1 -1
  145. package/dist/indieauth/bearer.d.ts.map +1 -1
  146. package/dist/indieauth/bearer.js +17 -16
  147. package/dist/indieauth/bearer.js.map +1 -1
  148. package/dist/indieauth/client-id.d.ts +10 -0
  149. package/dist/indieauth/client-id.d.ts.map +1 -0
  150. package/dist/indieauth/client-id.js +30 -0
  151. package/dist/indieauth/client-id.js.map +1 -0
  152. package/dist/indieauth/connected-apps.d.ts +4 -0
  153. package/dist/indieauth/connected-apps.d.ts.map +1 -1
  154. package/dist/indieauth/connected-apps.js +149 -20
  155. package/dist/indieauth/connected-apps.js.map +1 -1
  156. package/dist/indieauth/consent.d.ts.map +1 -1
  157. package/dist/indieauth/consent.js +5 -1
  158. package/dist/indieauth/consent.js.map +1 -1
  159. package/dist/indieauth/grants.d.ts +2 -7
  160. package/dist/indieauth/grants.d.ts.map +1 -1
  161. package/dist/indieauth/grants.js.map +1 -1
  162. package/dist/indieauth/redeem.d.ts.map +1 -1
  163. package/dist/indieauth/redeem.js +10 -5
  164. package/dist/indieauth/redeem.js.map +1 -1
  165. package/dist/indieauth/request.d.ts +8 -4
  166. package/dist/indieauth/request.d.ts.map +1 -1
  167. package/dist/indieauth/request.js +29 -30
  168. package/dist/indieauth/request.js.map +1 -1
  169. package/dist/indieauth/token.js +1 -1
  170. package/dist/indieauth/token.js.map +1 -1
  171. package/dist/indieauth/tokens.d.ts +28 -7
  172. package/dist/indieauth/tokens.d.ts.map +1 -1
  173. package/dist/indieauth/tokens.js +26 -5
  174. package/dist/indieauth/tokens.js.map +1 -1
  175. package/dist/micropub/create.d.ts +22 -0
  176. package/dist/micropub/create.d.ts.map +1 -1
  177. package/dist/micropub/create.js +107 -8
  178. package/dist/micropub/create.js.map +1 -1
  179. package/dist/micropub/endpoint.d.ts.map +1 -1
  180. package/dist/micropub/endpoint.js +71 -20
  181. package/dist/micropub/endpoint.js.map +1 -1
  182. package/dist/micropub/media.d.ts +4 -2
  183. package/dist/micropub/media.d.ts.map +1 -1
  184. package/dist/micropub/media.js +41 -37
  185. package/dist/micropub/media.js.map +1 -1
  186. package/dist/micropub/update.d.ts +6 -2
  187. package/dist/micropub/update.d.ts.map +1 -1
  188. package/dist/micropub/update.js +31 -3
  189. package/dist/micropub/update.js.map +1 -1
  190. package/dist/notify.d.ts.map +1 -1
  191. package/dist/notify.js +2 -5
  192. package/dist/notify.js.map +1 -1
  193. package/dist/web/absolute-urls.d.ts +2 -0
  194. package/dist/web/absolute-urls.d.ts.map +1 -0
  195. package/dist/web/absolute-urls.js +22 -0
  196. package/dist/web/absolute-urls.js.map +1 -0
  197. package/dist/web/context.d.ts +29 -1
  198. package/dist/web/context.d.ts.map +1 -1
  199. package/dist/web/context.js +33 -0
  200. package/dist/web/context.js.map +1 -1
  201. package/dist/web/conversation.d.ts.map +1 -1
  202. package/dist/web/conversation.js +5 -4
  203. package/dist/web/conversation.js.map +1 -1
  204. package/dist/web/documents.d.ts +19 -10
  205. package/dist/web/documents.d.ts.map +1 -1
  206. package/dist/web/documents.js +28 -13
  207. package/dist/web/documents.js.map +1 -1
  208. package/dist/web/feed-item.d.ts +25 -6
  209. package/dist/web/feed-item.d.ts.map +1 -1
  210. package/dist/web/feed-item.js +31 -7
  211. package/dist/web/feed-item.js.map +1 -1
  212. package/dist/web/feed-json.d.ts +3 -1
  213. package/dist/web/feed-json.d.ts.map +1 -1
  214. package/dist/web/feed-json.js +2 -0
  215. package/dist/web/feed-json.js.map +1 -1
  216. package/dist/web/feed-source.d.ts +6 -0
  217. package/dist/web/feed-source.d.ts.map +1 -1
  218. package/dist/web/feed-source.js.map +1 -1
  219. package/dist/web/feeds.d.ts.map +1 -1
  220. package/dist/web/feeds.js +2 -0
  221. package/dist/web/feeds.js.map +1 -1
  222. package/dist/web/html-attributes.d.ts +3 -0
  223. package/dist/web/html-attributes.d.ts.map +1 -0
  224. package/dist/web/html-attributes.js +15 -0
  225. package/dist/web/html-attributes.js.map +1 -0
  226. package/dist/web/index.d.ts +1 -1
  227. package/dist/web/index.d.ts.map +1 -1
  228. package/dist/web/index.js +1 -1
  229. package/dist/web/index.js.map +1 -1
  230. package/dist/web/negotiate.d.ts +2 -0
  231. package/dist/web/negotiate.d.ts.map +1 -1
  232. package/dist/web/negotiate.js +2 -1
  233. package/dist/web/negotiate.js.map +1 -1
  234. package/dist/web/render.d.ts +8 -0
  235. package/dist/web/render.d.ts.map +1 -1
  236. package/dist/web/render.js +5 -1
  237. package/dist/web/render.js.map +1 -1
  238. package/dist/web/routes.d.ts.map +1 -1
  239. package/dist/web/routes.js +14 -10
  240. package/dist/web/routes.js.map +1 -1
  241. package/dist/webmention/service.d.ts.map +1 -1
  242. package/dist/webmention/service.js +7 -2
  243. package/dist/webmention/service.js.map +1 -1
  244. package/package.json +1 -1
  245. package/themes/default/README.md +15 -0
  246. package/themes/default/layouts/base.njk +2 -0
  247. package/themes/default/layouts/post.njk +7 -1
  248. package/themes/default/partials/location.njk +12 -0
  249. package/themes/default/partials/post-list.njk +2 -0
  250. package/themes/default/partials/read.njk +5 -0
@@ -3,6 +3,7 @@
3
3
  Only your own connections, each with a Revoke button that names the app,
4
4
  so a screen reader moving between buttons hears which one it is on. #}
5
5
  {% extends "layouts/shell.njk" %}
6
+ {% import "components/fields.njk" as field %}
6
7
 
7
8
  {% block title %}Connected apps{% endblock %}
8
9
 
@@ -13,8 +14,9 @@
13
14
  <p class="admin-hint">
14
15
  These apps signed in as you and can act as you, within the permissions
15
16
  listed. An app that keeps using its connection stays connected; one left
16
- unused is disconnected on the date shown. Revoking disconnects it now:
17
- its next request is refused, and it has to ask you again.
17
+ unused is disconnected on the date shown. A token you created works
18
+ until the date shown. Revoking disconnects it now: its next request is
19
+ refused, and it has to ask you again.
18
20
  </p>
19
21
 
20
22
  <table class="admin-list">
@@ -32,7 +34,13 @@
32
34
  <tbody>
33
35
  {% for connection in connections %}
34
36
  <tr>
35
- <td><a href="{{ connection.url }}">{{ connection.name }}</a></td>
37
+ <td>
38
+ {% if connection.url %}
39
+ <a href="{{ connection.url }}">{{ connection.name }}</a>
40
+ {% else %}
41
+ {{ connection.name }} <span class="admin-status">Token you created</span>
42
+ {% endif %}
43
+ </td>
36
44
  <td>
37
45
  <ul>
38
46
  {% for scope in connection.scopes %}
@@ -71,4 +79,102 @@
71
79
  is listed here, with a button to disconnect it.
72
80
  </p>
73
81
  {% endif %}
82
+
83
+ <h2 id="create-token">Create a token</h2>
84
+
85
+ {% if createToken.created %}
86
+ <div class="admin-flash" role="status">
87
+ {{ field.text('created-token', 'created-token', 'Token for ' ~ createToken.created.name, createToken.created.token,
88
+ readonly=true, spellcheck='false',
89
+ hint='Copy it now. It will not be shown again: the site keeps only a fingerprint of it.') }}
90
+ </div>
91
+ {% endif %}
92
+
93
+ {% if createToken.problems.name or createToken.problems.scopes or createToken.problems.expires %}
94
+ {% call field.summary('Nothing was saved. Fix the fields marked below and try again.') %}
95
+ {{ field.problem('create-token-name', createToken.problems.name) }}
96
+ {{ field.problem('create-token-scope-profile', createToken.problems.scopes) }}
97
+ {{ field.problem('create-token-expires', createToken.problems.expires) }}
98
+ {% endcall %}
99
+ {% endif %}
100
+
101
+ <p class="admin-hint">
102
+ Some tools and scripts cannot sign in, but accept a token you paste in,
103
+ such as the Manual tab of micropub.rocks. A token acts as you on this
104
+ site's Micropub endpoint, with only the permissions you tick, until it
105
+ expires or you revoke it above.
106
+ </p>
107
+
108
+ <form method="post" action="{{ createToken.url }}">
109
+ <input type="hidden" name="csrf_token" value="{{ csrfToken }}" />
110
+ {{ field.text('create-token-name', 'name', 'Name', createToken.name,
111
+ error=createToken.problems.name, required=true,
112
+ hint='What will use it, such as Publishing script.') }}
113
+ <fieldset>
114
+ <legend>It may</legend>
115
+ {% for scope in createToken.scopes %}
116
+ {{ field.checkbox('create-token-scope-' ~ scope.name, 'scope', scope.label, checked=scope.checked, value=scope.name,
117
+ error=(createToken.problems.scopes if loop.first else '')) }}
118
+ {% endfor %}
119
+ </fieldset>
120
+ {% call field.select('create-token-expires', 'expires', 'Expires after', error=createToken.problems.expires) %}
121
+ {% for expiry in createToken.expiries %}
122
+ <option value="{{ expiry.days }}"{% if expiry.selected %} selected{% endif %}>{% if expiry.days == 365 %}1 year{% else %}{{ expiry.days }} days{% endif %}</option>
123
+ {% endfor %}
124
+ {% endcall %}
125
+ <button type="submit">Create token</button>
126
+ </form>
127
+
128
+ <h2 id="without-pkce">Apps allowed without PKCE</h2>
129
+
130
+ {% if withoutPkce.problem %}
131
+ {% call field.summary('Nothing was saved. Fix the field marked below and try again.') %}
132
+ {{ field.problem('without-pkce-client', withoutPkce.problem) }}
133
+ {% endcall %}
134
+ {% endif %}
135
+
136
+ <p class="admin-hint">
137
+ PKCE protects a sign-in when somebody intercepts the one-time code an app
138
+ is handed: without the secret the app kept, the code is useless. Every app
139
+ must use it, unless you list it here. List only an app you trust that
140
+ cannot sign in otherwise, such as iA Writer. A listed app is let in without
141
+ PKCE only when it sends you back to an https address on its own host, and
142
+ the consent screen tells you when it is.
143
+ </p>
144
+
145
+ {% if withoutPkce.clients | length %}
146
+ <table class="admin-list">
147
+ <caption class="admin-visually-hidden">Apps allowed without PKCE</caption>
148
+ <thead>
149
+ <tr>
150
+ <th scope="col">client_id</th>
151
+ <th scope="col">Actions</th>
152
+ </tr>
153
+ </thead>
154
+ <tbody>
155
+ {% for client in withoutPkce.clients %}
156
+ <tr>
157
+ <td><code>{{ client }}</code></td>
158
+ <td class="admin-actions">
159
+ <form method="post" action="{{ withoutPkce.removeUrl }}">
160
+ <input type="hidden" name="csrf_token" value="{{ csrfToken }}" />
161
+ <input type="hidden" name="{{ withoutPkce.field }}" value="{{ client }}" />
162
+ <button type="submit">Remove {{ client }}</button>
163
+ </form>
164
+ </td>
165
+ </tr>
166
+ {% endfor %}
167
+ </tbody>
168
+ </table>
169
+ {% else %}
170
+ <p>No apps are listed. Every app must use PKCE to sign in.</p>
171
+ {% endif %}
172
+
173
+ <form method="post" action="{{ withoutPkce.addUrl }}">
174
+ <input type="hidden" name="csrf_token" value="{{ csrfToken }}" />
175
+ {{ field.text('without-pkce-client', withoutPkce.field, 'App&rsquo;s client_id', withoutPkce.value,
176
+ error=withoutPkce.problem, inputmode='url', spellcheck='false', required=true,
177
+ hint='The URL the app names itself by when it signs in, as App activity shows it, such as <code>https://ia.net/writer</code>.') }}
178
+ <button type="submit">Allow without PKCE</button>
179
+ </form>
74
180
  {% endblock %}
@@ -2,13 +2,17 @@ import type { Context, Hono } from 'hono';
2
2
  import type { Document, DocumentType } from '../content/document.ts';
3
3
  import type { Enclosure } from '../content/enclosure.ts';
4
4
  import type { Photo } from '../content/photo.ts';
5
+ import type { PostLocation } from '../content/location.ts';
5
6
  import type { ContentStore, ListAllOptions } from '../content/store.ts';
7
+ import type { StoredVisibility } from '../content/visibility.ts';
6
8
  import type { ResolvedConfig } from '../config.ts';
7
9
  import type { DocumentChange } from '../content/sync.ts';
8
10
  import type { GeekityEnv } from '../env.ts';
9
11
  import type { UndescribedImage } from '../images/alt-text.ts';
10
12
  import type { EnclosureForm } from './enclosure-field.ts';
13
+ import type { LocationForm } from './location-field.ts';
11
14
  import type { PhotoRow } from './photo-field.ts';
15
+ import type { ReadOfForm } from './read-field.ts';
12
16
  /**
13
17
  * Everything that differs between the posts screens and the pages screens.
14
18
  *
@@ -258,9 +262,21 @@ export interface EditorForm {
258
262
  likeOf: string;
259
263
  /** The page this one bookmarks, the mf2 `bookmark-of` (TASK-169). Posts only. */
260
264
  bookmarkOf: string;
265
+ /**
266
+ * How far the post's author got with what they read, the mf2 `read-status`
267
+ * (TASK-229), as the file or the form spells it. Posts only.
268
+ */
269
+ readStatus: string;
270
+ /** What was read, the mf2 `read-of` (TASK-229). Posts only. */
271
+ readOf: ReadOfForm;
261
272
  /** The language it is written in, the `lang` key; empty for the site's. */
262
273
  lang: string;
263
274
  draft: boolean;
275
+ /**
276
+ * Whether the document is listed or only served at its URL (TASK-227), or a
277
+ * value the site does not recognize, which hides it until one is chosen.
278
+ */
279
+ visibility: StoredVisibility;
264
280
  /** Whether `eleventyExcludeFromCollections` is set. Pages only. */
265
281
  exclude: boolean;
266
282
  /** Whether the page offers a contact form. Pages only. */
@@ -280,6 +296,12 @@ export interface EditorForm {
280
296
  enclosure: EnclosureForm;
281
297
  /** The post's photos (TASK-166), without the blank row the editor adds. Posts only. */
282
298
  photos: PhotoRow[];
299
+ /**
300
+ * Where the post was written (TASK-223). Posts only; blank on a page. It is
301
+ * the one field that is not written into the file: the save puts it in
302
+ * `data/locations.json` under the post's permalink (decision-29).
303
+ */
304
+ location: LocationForm;
283
305
  /** The ids of the declared syndication targets it selects (TASK-155). Posts only. */
284
306
  syndicateTo: string[];
285
307
  body: string;
@@ -301,8 +323,12 @@ export declare function blankForm(kind: DocumentKind, timezone?: string, now?: D
301
323
  * {@link wallClockIn} keeps whatever precision the instant has, so a form
302
324
  * submitted with the field untouched writes back the very instant it was
303
325
  * filled in from.
326
+ *
327
+ * `location` is what `data/locations.json` holds for the post (decision-29),
328
+ * which a document does not carry. It is required because a form loaded
329
+ * without it would remove the stored location on save.
304
330
  */
305
- export declare function formFor(document: Document, timezone?: string): EditorForm;
331
+ export declare function formFor(document: Document, timezone: string, location: PostLocation | undefined): EditorForm;
306
332
  /**
307
333
  * The document of this kind with this slug.
308
334
  *
@@ -327,6 +353,8 @@ export interface DocumentRow {
327
353
  trashed: boolean;
328
354
  /** Whether its date has not arrived, so the public site is holding it back. */
329
355
  scheduled: boolean;
356
+ /** Whether its `visibility` is one the site does not recognize, so it is not served. */
357
+ hidden: boolean;
330
358
  /** Where the editor for it lives. */
331
359
  editUrl: string;
332
360
  /** Its public URL, or `undefined` when the public site would not serve it. */
@@ -1 +1 @@
1
- {"version":3,"file":"documents.d.ts","sourceRoot":"","sources":["../../src/admin/documents.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"documents.d.ts","sourceRoot":"","sources":["../../src/admin/documents.ts"],"names":[],"mappings":"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"}
@@ -5,17 +5,20 @@ import { renderMarkdown } from '../content/markdown.js';
5
5
  import { parseDocument } from '../content/parser.js';
6
6
  import { PINNED_FRONT_MATTER_KEY, PINNED_POST_LIMIT, pinnedAt } from '../content/pinned.js';
7
7
  import { postLabel, replyTarget } from '../content/post-type.js';
8
+ import { isReadStatus, READ_OF_FRONT_MATTER_KEY, READ_STATUS_FRONT_MATTER_KEY, READ_STATUS_LABELS, READ_STATUSES, readWork, readWorkFrontMatter, } from '../content/read.js';
8
9
  import { ENCLOSURE_FRONT_MATTER_KEY, enclosureOf, isWebUrl, TRANSCRIPT_TYPES, } from '../content/enclosure.js';
9
10
  import { PHOTO_FRONT_MATTER_KEY, photoFrontMatter } from '../content/photo.js';
11
+ import { postLocations } from '../content/locations.js';
10
12
  import { contentFilePath, freeSlug, saveDocument } from '../content/save.js';
11
13
  import { scheduledFor } from '../content/schedule.js';
12
14
  import { htmlToText } from '../content/search.js';
13
15
  import { defaultPermalink, slugify } from '../content/slug.js';
14
16
  import { DuplicatePermalinkError, isTrashedPath, TRASH_DIRECTORY } from '../content/store.js';
15
17
  import { calendarDayIn, DEFAULT_TIMEZONE, toUtcInstant, wallClockIn, zoneLabel, } from '../content/time.js';
18
+ import { isVisibility, VISIBILITY_FRONT_MATTER_KEY, visibilityOf } from '../content/visibility.js';
16
19
  import { normalizeBody, serializeDocument } from '../content/writer.js';
17
20
  import { readAltTexts, undescribedImages, undescribedPhotos } from '../images/alt-text.js';
18
- import { isPublicDocument } from '../web/documents.js';
21
+ import { isServed } from '../web/documents.js';
19
22
  import { LANG_FRONT_MATTER_KEY } from '../web/locale.js';
20
23
  import { absoluteUrl } from '../web/negotiate.js';
21
24
  import { COMMENTS_FRONT_MATTER_KEY } from '../comments/policy.js';
@@ -30,7 +33,9 @@ import { ADMIN_PREFIX } from './session.js';
30
33
  import { ADMIN_TEMPLATES } from './templates.js';
31
34
  import { UPLOADS_PATH } from './uploads.js';
32
35
  import { BLANK_ALTERNATE_ROW, BLANK_ENCLOSURE_FORM, ENCLOSURE_FIELDS, enclosureChoices, enclosureForm, enclosureFrontMatter, readEnclosureForm, resolveEnclosure, } from './enclosure-field.js';
36
+ import { BLANK_LOCATION_FORM, LOCATION_FIELDS, locationForm, readLocationForm, resolveLocation, } from './location-field.js';
33
37
  import { PHOTO_FIELDS, photoChoices, photoRows, photoRowViews, readPhotoForm, resolvePhotos, } from './photo-field.js';
38
+ import { BLANK_READ_OF_FORM, READ_FIELDS, readOfForm, resolveRead, submittedReadOfForm, } from './read-field.js';
34
39
  import { SYNDICATE_TO_FRONT_MATTER_KEY, syndicateToOf, syndicationTargetsReader, } from '../webmention/syndication.js';
35
40
  /**
36
41
  * The Eleventy key that keeps a document out of every collection.
@@ -54,6 +59,11 @@ function commentSetting(value) {
54
59
  ? value
55
60
  : COMMENT_SETTINGS.site;
56
61
  }
62
+ function formVisibility(value) {
63
+ if (value === '')
64
+ return 'public';
65
+ return isVisibility(value) ? value : { unrecognized: value };
66
+ }
57
67
  /** What a document's front matter already says about comments. */
58
68
  function commentSettingOf(document) {
59
69
  const own = document.extra[COMMENTS_FRONT_MATTER_KEY];
@@ -174,7 +184,13 @@ export function mountDocumentScreens(app, options) {
174
184
  const document = findBySlug(c.var.store, kind, c.req.param('slug'));
175
185
  if (document === undefined)
176
186
  return c.notFound();
177
- return renderEditor(c, { kind, render, document, form: formFor(document, siteTimezone(c)) });
187
+ const location = postLocations(c.var.config.dataDir).read(document.permalink);
188
+ return renderEditor(c, {
189
+ kind,
190
+ render,
191
+ document,
192
+ form: formFor(document, siteTimezone(c), location),
193
+ });
178
194
  });
179
195
  app.post(`${kind.basePath}/:slug`, async (c) => {
180
196
  const document = findBySlug(c.var.store, kind, c.req.param('slug'));
@@ -208,14 +224,18 @@ async function saveFromForm(c, options) {
208
224
  author: text(body['author']).trim(),
209
225
  inReplyTo: text(body['in-reply-to']).trim(),
210
226
  ...citationFields((property) => (kind.type === 'post' ? text(body[property]).trim() : '')),
227
+ readStatus: kind.type === 'post' ? text(body[READ_FIELDS.status]).trim() : '',
228
+ readOf: kind.type === 'post' ? submittedReadOfForm(body) : BLANK_READ_OF_FORM,
211
229
  lang: text(body['lang']).trim(),
212
230
  draft: body['draft'] !== undefined,
231
+ visibility: formVisibility(text(body['visibility'])),
213
232
  exclude: body['exclude'] !== undefined,
214
233
  contact: body['contact'] !== undefined,
215
234
  pinned: kind.type === 'post' && body['pinned'] !== undefined,
216
235
  comments: commentSetting(text(body['comments'])),
217
236
  enclosure: kind.type === 'post' ? readEnclosureForm(body) : BLANK_ENCLOSURE_FORM,
218
237
  photos: kind.type === 'post' ? readPhotoForm(body) : [],
238
+ location: kind.type === 'post' ? readLocationForm(body) : BLANK_LOCATION_FORM,
219
239
  syndicateTo: kind.type === 'post'
220
240
  ? syndicationTargetsReader(contentDir)()
221
241
  .filter((target) => body[syndicateToField(target)] !== undefined)
@@ -287,6 +307,7 @@ export async function writeDocument(site, write) {
287
307
  if (kind.type === 'post' && form.inReplyTo !== '' && replyTarget(form) === undefined) {
288
308
  return refused('In reply to has to be a web address, like https://example.com/a-post/.');
289
309
  }
310
+ let read;
290
311
  if (kind.type === 'post') {
291
312
  for (const property of CITATION_PROPERTIES) {
292
313
  const cited = form[CITATION_FIELDS[property]];
@@ -294,6 +315,13 @@ export async function writeDocument(site, write) {
294
315
  return refused(`${CITATION_LABELS[property]} has to be a web address, like https://example.com/a-post/.`);
295
316
  }
296
317
  }
318
+ const resolved = resolveRead(form.readStatus, form.readOf);
319
+ if ('error' in resolved)
320
+ return refused(resolved.error);
321
+ read = resolved.read;
322
+ }
323
+ if (read !== undefined && form.description !== '') {
324
+ return refused('A read is described by what it says, so it keeps no Description. Empty Description to save it.');
297
325
  }
298
326
  if (form.lang !== '' && !LANGUAGE_TAG_PATTERN.test(form.lang)) {
299
327
  return refused('That is not a language tag, such as en, fr or pt-BR.');
@@ -308,6 +336,13 @@ export async function writeDocument(site, write) {
308
336
  return refused(photos.error);
309
337
  media = { recording: resolved.enclosure, photos: photos.photos };
310
338
  }
339
+ let location;
340
+ if (kind.type === 'post') {
341
+ const resolved = resolveLocation(form.location);
342
+ if ('error' in resolved)
343
+ return refused(resolved.error);
344
+ location = resolved.location;
345
+ }
311
346
  // TASK-207: a pin is new when the file does not carry one yet, and only a
312
347
  // new one can take an author past Mastodon's limit.
313
348
  if (form.pinned && (document === undefined || pinnedAt(document) === undefined)) {
@@ -346,6 +381,7 @@ export async function writeDocument(site, write) {
346
381
  slugify(form.title) ||
347
382
  (document?.slug ?? '') ||
348
383
  noteSlug(form.body) ||
384
+ slugify(form.readOf.name) ||
349
385
  'untitled';
350
386
  const trashed = document !== undefined && isTrashedPath(document.path);
351
387
  // The calendar day the document is filed under: the site zone's day at its
@@ -421,6 +457,13 @@ export async function writeDocument(site, write) {
421
457
  if (renamedFrom !== undefined) {
422
458
  await rm(path.join(contentDir, ...renamedFrom.path.split('/')), { force: true });
423
459
  }
460
+ if (kind.type === 'post') {
461
+ const locations = postLocations(config.dataDir);
462
+ if (document !== undefined && document.permalink !== saved.permalink) {
463
+ await locations.move(document.permalink, saved.permalink);
464
+ }
465
+ await locations.set(saved.permalink, location);
466
+ }
424
467
  // Announced rather than left to the watcher: the index already holds what
425
468
  // was written, so the watcher's re-read is a no-op and nobody would ever
426
469
  // hear that this post was published. Awaited, so a subscriber that writes
@@ -482,7 +525,7 @@ function promisedDocument(document, now) {
482
525
  if (document === undefined)
483
526
  return undefined;
484
527
  const announced = document.activitypub?.published !== undefined;
485
- return isPublicDocument(document, now) || announced ? document : undefined;
528
+ return isServed(document, now) || announced ? document : undefined;
486
529
  }
487
530
  /**
488
531
  * The URLs a document is saved as having lived at (TASK-127).
@@ -633,6 +676,18 @@ function resolveExtra(kind, document, form, now, media, declared) {
633
676
  else
634
677
  extra[property] = cited;
635
678
  }
679
+ const resolved = resolveRead(form.readStatus, form.readOf);
680
+ if ('read' in resolved) {
681
+ const { read } = resolved;
682
+ if (read === undefined) {
683
+ delete extra[READ_OF_FRONT_MATTER_KEY];
684
+ delete extra[READ_STATUS_FRONT_MATTER_KEY];
685
+ }
686
+ else {
687
+ extra[READ_OF_FRONT_MATTER_KEY] = readWorkFrontMatter(read.of);
688
+ extra[READ_STATUS_FRONT_MATTER_KEY] = read.status;
689
+ }
690
+ }
636
691
  }
637
692
  // The checkboxes speak for the targets the site declares (TASK-155). An id
638
693
  // the file lists that names no declared target has no checkbox, so it is
@@ -657,6 +712,12 @@ function resolveExtra(kind, document, form, now, media, declared) {
657
712
  else if (pinned === undefined)
658
713
  extra[PINNED_FRONT_MATTER_KEY] = toUtcInstant(now, 'UTC');
659
714
  }
715
+ if (form.visibility === 'public')
716
+ delete extra[VISIBILITY_FRONT_MATTER_KEY];
717
+ else if (typeof form.visibility === 'string')
718
+ extra[VISIBILITY_FRONT_MATTER_KEY] = form.visibility;
719
+ else
720
+ extra[VISIBILITY_FRONT_MATTER_KEY] = form.visibility.unrecognized;
660
721
  // Empty is the site's language, which is the key's absence (TASK-154).
661
722
  if (form.lang === '')
662
723
  delete extra[LANG_FRONT_MATTER_KEY];
@@ -984,14 +1045,18 @@ export function blankForm(kind, timezone = DEFAULT_TIMEZONE, now = new Date()) {
984
1045
  author: '',
985
1046
  inReplyTo: '',
986
1047
  ...citationFields(() => ''),
1048
+ readStatus: '',
1049
+ readOf: BLANK_READ_OF_FORM,
987
1050
  lang: '',
988
1051
  draft: false,
1052
+ visibility: 'public',
989
1053
  exclude: false,
990
1054
  contact: false,
991
1055
  pinned: false,
992
1056
  comments: COMMENT_SETTINGS.site,
993
1057
  enclosure: BLANK_ENCLOSURE_FORM,
994
1058
  photos: [],
1059
+ location: BLANK_LOCATION_FORM,
995
1060
  syndicateTo: [],
996
1061
  body: '',
997
1062
  hash: '',
@@ -1004,8 +1069,12 @@ export function blankForm(kind, timezone = DEFAULT_TIMEZONE, now = new Date()) {
1004
1069
  * {@link wallClockIn} keeps whatever precision the instant has, so a form
1005
1070
  * submitted with the field untouched writes back the very instant it was
1006
1071
  * filled in from.
1072
+ *
1073
+ * `location` is what `data/locations.json` holds for the post (decision-29),
1074
+ * which a document does not carry. It is required because a form loaded
1075
+ * without it would remove the stored location on save.
1007
1076
  */
1008
- export function formFor(document, timezone = DEFAULT_TIMEZONE) {
1077
+ export function formFor(document, timezone, location) {
1009
1078
  return {
1010
1079
  title: document.title,
1011
1080
  slug: document.slug,
@@ -1018,16 +1087,22 @@ export function formFor(document, timezone = DEFAULT_TIMEZONE) {
1018
1087
  inReplyTo: document.inReplyTo ?? '',
1019
1088
  // As the file spells it, so a save writes back what it read.
1020
1089
  ...citationFields((property) => document.type === 'post' ? citationText(document.extra[property]) : ''),
1090
+ readStatus: document.type === 'post' && typeof document.extra[READ_STATUS_FRONT_MATTER_KEY] === 'string'
1091
+ ? document.extra[READ_STATUS_FRONT_MATTER_KEY]
1092
+ : '',
1093
+ readOf: readOfForm(document.type === 'post' ? readWork(document.extra[READ_OF_FRONT_MATTER_KEY]) : undefined),
1021
1094
  lang: typeof document.extra[LANG_FRONT_MATTER_KEY] === 'string'
1022
1095
  ? document.extra[LANG_FRONT_MATTER_KEY]
1023
1096
  : '',
1024
1097
  draft: document.draft,
1098
+ visibility: visibilityOf(document),
1025
1099
  exclude: document.extra[EXCLUDE_KEY] === true,
1026
1100
  contact: document.extra[CONTACT_FRONT_MATTER_KEY] === true,
1027
1101
  pinned: pinnedAt(document) !== undefined,
1028
1102
  comments: commentSettingOf(document),
1029
1103
  enclosure: document.type === 'post' ? enclosureForm(document) : BLANK_ENCLOSURE_FORM,
1030
1104
  photos: document.type === 'post' ? photoRows(document) : [],
1105
+ location: document.type === 'post' ? locationForm(location) : BLANK_LOCATION_FORM,
1031
1106
  syndicateTo: document.type === 'post' ? syndicateToOf(document.extra) : [],
1032
1107
  body: document.body,
1033
1108
  hash: document.hash,
@@ -1082,6 +1157,12 @@ async function renderEditor(c, options) {
1082
1157
  photoFields: PHOTO_FIELDS,
1083
1158
  photoRows: photoRowViews(form.photos, readAltTexts(c.var.config.contentDir)),
1084
1159
  photoChoices: await photoChoices(c.var.config.contentDir),
1160
+ locationFields: LOCATION_FIELDS,
1161
+ readFields: READ_FIELDS,
1162
+ readStatuses: READ_STATUSES.map((value) => ({ value, label: READ_STATUS_LABELS[value] })),
1163
+ ...(form.readStatus === '' || isReadStatus(form.readStatus)
1164
+ ? {}
1165
+ : { unrecognizedReadStatus: form.readStatus }),
1085
1166
  // TASK-155: one checkbox per target the site declares.
1086
1167
  syndicationTargets: syndicationTargetsReader(c.var.config.contentDir)().map((target) => ({
1087
1168
  ...target,
@@ -1101,7 +1182,7 @@ async function renderEditor(c, options) {
1101
1182
  listUrl: kind.basePath,
1102
1183
  previewUrl: PREVIEW_PATH,
1103
1184
  uploadUrl: UPLOADS_PATH,
1104
- viewUrl: document !== undefined && isPublicDocument(document, now) ? document.permalink : undefined,
1185
+ viewUrl: document !== undefined && isServed(document, now) ? document.permalink : undefined,
1105
1186
  // Named beside the date field, because a wall clock with no zone on it is
1106
1187
  // exactly the ambiguity decision-11 exists to remove.
1107
1188
  ...(kind.dated ? { dateZone: zoneLabel(form.date === '' ? now : form.date, timezone) } : {}),
@@ -1150,7 +1231,7 @@ function pageRole(kind, document, c) {
1150
1231
  return undefined;
1151
1232
  }
1152
1233
  function listRow(kind, document, now, role) {
1153
- const isPublic = isPublicDocument(document, now);
1234
+ const isPublic = isServed(document, now);
1154
1235
  return {
1155
1236
  title: postLabel(document),
1156
1237
  slug: document.slug,
@@ -1165,6 +1246,7 @@ function listRow(kind, document, now, role) {
1165
1246
  draft: document.draft,
1166
1247
  trashed: isTrashedPath(document.path),
1167
1248
  scheduled: scheduledFor(document, now) !== undefined,
1249
+ hidden: typeof visibilityOf(document) !== 'string',
1168
1250
  editUrl: editorPath(kind, document.slug),
1169
1251
  viewUrl: isPublic ? document.permalink : undefined,
1170
1252
  role,