@geekity/cms 0.22.0 → 0.24.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 +19 -4
- package/admin/pages/documents/editor.njk +18 -0
- package/admin/static/editor.js +1 -1
- package/dist/admin/comments.js +2 -2
- package/dist/admin/comments.js.map +1 -1
- package/dist/admin/documents.d.ts +36 -7
- package/dist/admin/documents.d.ts.map +1 -1
- package/dist/admin/documents.js +140 -29
- package/dist/admin/documents.js.map +1 -1
- package/dist/admin/editor-layout.d.ts +1 -1
- package/dist/admin/editor-layout.d.ts.map +1 -1
- package/dist/admin/editor-layout.js +6 -1
- package/dist/admin/editor-layout.js.map +1 -1
- package/dist/admin/event-field.d.ts +26 -0
- package/dist/admin/event-field.d.ts.map +1 -0
- package/dist/admin/event-field.js +74 -0
- package/dist/admin/event-field.js.map +1 -0
- package/dist/admin/federation.js +3 -3
- package/dist/admin/federation.js.map +1 -1
- package/dist/admin/media.js +2 -2
- package/dist/admin/media.js.map +1 -1
- package/dist/admin/preview.d.ts.map +1 -1
- package/dist/admin/preview.js +16 -1
- package/dist/admin/preview.js.map +1 -1
- package/dist/admin/store.d.ts +9 -0
- package/dist/admin/store.d.ts.map +1 -1
- package/dist/admin/store.js +16 -5
- package/dist/admin/store.js.map +1 -1
- package/dist/avatars/avatars.js +1 -1
- package/dist/avatars/avatars.js.map +1 -1
- package/dist/comments/policy.d.ts +10 -0
- package/dist/comments/policy.d.ts.map +1 -1
- package/dist/comments/policy.js +12 -0
- package/dist/comments/policy.js.map +1 -1
- package/dist/comments/records.d.ts +5 -1
- package/dist/comments/records.d.ts.map +1 -1
- package/dist/comments/records.js +16 -2
- package/dist/comments/records.js.map +1 -1
- package/dist/content/event.d.ts +40 -0
- package/dist/content/event.d.ts.map +1 -0
- package/dist/content/event.js +51 -0
- package/dist/content/event.js.map +1 -0
- package/dist/content/handles.d.ts +22 -0
- package/dist/content/handles.d.ts.map +1 -0
- package/dist/content/handles.js +68 -0
- package/dist/content/handles.js.map +1 -0
- package/dist/content/markdown.d.ts +8 -2
- package/dist/content/markdown.d.ts.map +1 -1
- package/dist/content/markdown.js +55 -5
- package/dist/content/markdown.js.map +1 -1
- package/dist/content/parser.d.ts +3 -0
- package/dist/content/parser.d.ts.map +1 -1
- package/dist/content/parser.js +1 -1
- package/dist/content/parser.js.map +1 -1
- package/dist/content/post-type.d.ts +12 -8
- package/dist/content/post-type.d.ts.map +1 -1
- package/dist/content/post-type.js +12 -2
- package/dist/content/post-type.js.map +1 -1
- package/dist/content/rsvp.d.ts +29 -0
- package/dist/content/rsvp.d.ts.map +1 -0
- package/dist/content/rsvp.js +49 -0
- package/dist/content/rsvp.js.map +1 -0
- package/dist/content/save.d.ts +2 -1
- package/dist/content/save.d.ts.map +1 -1
- package/dist/content/save.js +10 -3
- package/dist/content/save.js.map +1 -1
- package/dist/content/store.d.ts +11 -4
- package/dist/content/store.d.ts.map +1 -1
- package/dist/content/store.js +15 -4
- package/dist/content/store.js.map +1 -1
- package/dist/content/sync.d.ts.map +1 -1
- package/dist/content/sync.js +7 -6
- package/dist/content/sync.js.map +1 -1
- package/dist/env.d.ts +3 -0
- package/dist/env.d.ts.map +1 -1
- package/dist/federation/article.d.ts +9 -3
- package/dist/federation/article.d.ts.map +1 -1
- package/dist/federation/article.js +90 -34
- package/dist/federation/article.js.map +1 -1
- package/dist/federation/cited-post.d.ts +13 -0
- package/dist/federation/cited-post.d.ts.map +1 -0
- package/dist/federation/cited-post.js +75 -0
- package/dist/federation/cited-post.js.map +1 -0
- package/dist/federation/delivery.d.ts.map +1 -1
- package/dist/federation/delivery.js +31 -2
- package/dist/federation/delivery.js.map +1 -1
- package/dist/federation/handles.d.ts +28 -0
- package/dist/federation/handles.d.ts.map +1 -0
- package/dist/federation/handles.js +65 -0
- package/dist/federation/handles.js.map +1 -0
- package/dist/federation/inbox.d.ts +2 -1
- package/dist/federation/inbox.d.ts.map +1 -1
- package/dist/federation/inbox.js +11 -3
- package/dist/federation/inbox.js.map +1 -1
- package/dist/federation/mount.d.ts.map +1 -1
- package/dist/federation/mount.js +18 -2
- package/dist/federation/mount.js.map +1 -1
- package/dist/federation/profiles.d.ts.map +1 -1
- package/dist/federation/profiles.js +2 -8
- package/dist/federation/profiles.js.map +1 -1
- package/dist/federation/site-loaders.d.ts +15 -0
- package/dist/federation/site-loaders.d.ts.map +1 -0
- package/dist/federation/site-loaders.js +19 -0
- package/dist/federation/site-loaders.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -1
- package/dist/index.js.map +1 -1
- package/dist/indieauth/client.js +2 -2
- package/dist/indieauth/client.js.map +1 -1
- package/dist/micropub/create.d.ts +2 -1
- package/dist/micropub/create.d.ts.map +1 -1
- package/dist/micropub/create.js +57 -8
- package/dist/micropub/create.js.map +1 -1
- package/dist/micropub/endpoint.d.ts.map +1 -1
- package/dist/micropub/endpoint.js +12 -4
- package/dist/micropub/endpoint.js.map +1 -1
- package/dist/micropub/update.d.ts +3 -0
- package/dist/micropub/update.d.ts.map +1 -1
- package/dist/micropub/update.js +29 -4
- package/dist/micropub/update.js.map +1 -1
- package/dist/web/context.d.ts +32 -4
- package/dist/web/context.d.ts.map +1 -1
- package/dist/web/context.js +28 -1
- package/dist/web/context.js.map +1 -1
- package/dist/web/conversation.d.ts +26 -1
- package/dist/web/conversation.d.ts.map +1 -1
- package/dist/web/conversation.js +67 -10
- package/dist/web/conversation.js.map +1 -1
- package/dist/web/documents.d.ts +12 -0
- package/dist/web/documents.d.ts.map +1 -1
- package/dist/web/documents.js +20 -0
- package/dist/web/documents.js.map +1 -1
- package/dist/web/errors.d.ts.map +1 -1
- package/dist/web/errors.js +5 -3
- package/dist/web/errors.js.map +1 -1
- package/dist/web/feed-item.d.ts.map +1 -1
- package/dist/web/feed-item.js +8 -3
- package/dist/web/feed-item.js.map +1 -1
- package/dist/web/llms.d.ts +8 -0
- package/dist/web/llms.d.ts.map +1 -1
- package/dist/web/llms.js +25 -7
- package/dist/web/llms.js.map +1 -1
- package/dist/web/maintenance.d.ts.map +1 -1
- package/dist/web/maintenance.js +5 -2
- package/dist/web/maintenance.js.map +1 -1
- package/dist/web/negotiate.d.ts +4 -2
- package/dist/web/negotiate.d.ts.map +1 -1
- package/dist/web/negotiate.js +17 -7
- package/dist/web/negotiate.js.map +1 -1
- package/dist/web/render.d.ts +3 -0
- package/dist/web/render.d.ts.map +1 -1
- package/dist/web/render.js +39 -6
- package/dist/web/render.js.map +1 -1
- package/dist/web/routes.d.ts.map +1 -1
- package/dist/web/routes.js +67 -25
- package/dist/web/routes.js.map +1 -1
- package/dist/web/templates.d.ts +4 -1
- package/dist/web/templates.d.ts.map +1 -1
- package/dist/web/templates.js +11 -0
- package/dist/web/templates.js.map +1 -1
- package/dist/webmention/cited-picture.d.ts +11 -4
- package/dist/webmention/cited-picture.d.ts.map +1 -1
- package/dist/webmention/cited-picture.js +22 -13
- package/dist/webmention/cited-picture.js.map +1 -1
- package/dist/webmention/cited-start.d.ts +10 -0
- package/dist/webmention/cited-start.d.ts.map +1 -0
- package/dist/webmention/cited-start.js +21 -0
- package/dist/webmention/cited-start.js.map +1 -0
- package/dist/webmention/fetch-public.d.ts +2 -2
- package/dist/webmention/fetch-public.d.ts.map +1 -1
- package/dist/webmention/fetch-public.js +1 -1
- package/dist/webmention/fetch-public.js.map +1 -1
- package/dist/webmention/html.d.ts +2 -0
- package/dist/webmention/html.d.ts.map +1 -1
- package/dist/webmention/html.js +6 -0
- package/dist/webmention/html.js.map +1 -1
- package/dist/webmention/index.d.ts +2 -1
- package/dist/webmention/index.d.ts.map +1 -1
- package/dist/webmention/index.js +1 -0
- package/dist/webmention/index.js.map +1 -1
- package/dist/webmention/microformats.d.ts +25 -2
- package/dist/webmention/microformats.d.ts.map +1 -1
- package/dist/webmention/microformats.js +38 -4
- package/dist/webmention/microformats.js.map +1 -1
- package/dist/webmention/pingback.d.ts +42 -0
- package/dist/webmention/pingback.d.ts.map +1 -0
- package/dist/webmention/pingback.js +229 -0
- package/dist/webmention/pingback.js.map +1 -0
- package/dist/webmention/receive.d.ts +20 -2
- package/dist/webmention/receive.d.ts.map +1 -1
- package/dist/webmention/receive.js +25 -16
- package/dist/webmention/receive.js.map +1 -1
- package/dist/webmention/reply-context.d.ts +65 -18
- package/dist/webmention/reply-context.d.ts.map +1 -1
- package/dist/webmention/reply-context.js +403 -99
- package/dist/webmention/reply-context.js.map +1 -1
- package/dist/webmention/reply-contexts.d.ts +3 -1
- package/dist/webmention/reply-contexts.d.ts.map +1 -1
- package/dist/webmention/reply-contexts.js +53 -17
- package/dist/webmention/reply-contexts.js.map +1 -1
- package/dist/webmention/routes.d.ts.map +1 -1
- package/dist/webmention/routes.js +2 -0
- package/dist/webmention/routes.js.map +1 -1
- package/dist/webmention/service.d.ts +11 -0
- package/dist/webmention/service.d.ts.map +1 -1
- package/dist/webmention/service.js +27 -6
- package/dist/webmention/service.js.map +1 -1
- package/dist/webmention/syndication.d.ts +6 -0
- package/dist/webmention/syndication.d.ts.map +1 -1
- package/dist/webmention/syndication.js +12 -0
- package/dist/webmention/syndication.js.map +1 -1
- package/package.json +7 -7
- package/themes/default/README.md +127 -37
- package/themes/default/layouts/410.njk +10 -0
- package/themes/default/layouts/base.njk +3 -0
- package/themes/default/layouts/page.njk +7 -0
- package/themes/default/layouts/post.njk +7 -4
- package/themes/default/layouts/search.njk +1 -1
- package/themes/default/partials/cited-page.njk +7 -0
- package/themes/default/partials/conversation.njk +25 -5
- package/themes/default/partials/event.njk +27 -0
- package/themes/default/partials/jsonld.njk +28 -0
- package/themes/default/partials/post-list.njk +5 -2
- package/themes/default/partials/reply-context.njk +24 -4
- package/themes/default/partials/rsvp.njk +7 -0
- package/themes/default/src/style.css +20 -0
- package/themes/default/static/style.css +35 -0
package/dist/admin/comments.js
CHANGED
|
@@ -2,7 +2,7 @@ import { postLabel } from '../content/post-type.js';
|
|
|
2
2
|
import { renderCommentMarkdown } from '../comments/markdown.js';
|
|
3
3
|
import { isModerationAction, moderateComment } from '../comments/moderate.js';
|
|
4
4
|
import { intakeComment } from '../comments/records.js';
|
|
5
|
-
import {
|
|
5
|
+
import { documentEditorPath, PAGE_KIND, POST_KIND } from './documents.js';
|
|
6
6
|
import { flash } from './flash.js';
|
|
7
7
|
import { findUserById } from './accounts.js';
|
|
8
8
|
import { formatInTimezone } from './formatting.js';
|
|
@@ -234,7 +234,7 @@ function commentRow(c, comment) {
|
|
|
234
234
|
postUrl: comment.permalink === '' ? null : comment.permalink,
|
|
235
235
|
editUrl: document === undefined
|
|
236
236
|
? null
|
|
237
|
-
:
|
|
237
|
+
: documentEditorPath(document.type === 'page' ? PAGE_KIND : POST_KIND, document),
|
|
238
238
|
inReplyTo: comment.inReplyTo,
|
|
239
239
|
};
|
|
240
240
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"comments.js","sourceRoot":"","sources":["../../src/admin/comments.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAGvD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"comments.js","sourceRoot":"","sources":["../../src/admin/comments.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Context, Hono } from 'hono';
|
|
2
2
|
import type { Document, DocumentType } from '../content/document.ts';
|
|
3
|
+
import type { HandleLearner } from '../federation/handles.ts';
|
|
3
4
|
import type { Enclosure } from '../content/enclosure.ts';
|
|
4
5
|
import type { Photo } from '../content/photo.ts';
|
|
5
6
|
import type { PostLocation } from '../content/location.ts';
|
|
@@ -15,6 +16,7 @@ import type { Refusal } from './editor-layout.ts';
|
|
|
15
16
|
import type { LocationForm } from './location-field.ts';
|
|
16
17
|
import type { PhotoRow } from './photo-field.ts';
|
|
17
18
|
import type { ReadOfForm } from './read-field.ts';
|
|
19
|
+
import type { EventForm } from './event-field.ts';
|
|
18
20
|
import type { ReplyContext } from '../webmention/reply-context.ts';
|
|
19
21
|
/**
|
|
20
22
|
* Everything that differs between the posts screens and the pages screens.
|
|
@@ -84,6 +86,13 @@ export declare const POST_KIND: DocumentKind;
|
|
|
84
86
|
export declare const PAGE_KIND: DocumentKind;
|
|
85
87
|
/** The URL of the editor for one document. */
|
|
86
88
|
export declare function editorPath(kind: DocumentKind, slug: string): string;
|
|
89
|
+
/**
|
|
90
|
+
* The URL of the editor for this document.
|
|
91
|
+
*
|
|
92
|
+
* A trashed document also names its file, because a live document may have
|
|
93
|
+
* taken its slug along with its URL (TASK-195).
|
|
94
|
+
*/
|
|
95
|
+
export declare function documentEditorPath(kind: DocumentKind, document: Pick<Document, 'slug' | 'path'>): string;
|
|
87
96
|
/** The URL of the editor for a document that does not exist yet. */
|
|
88
97
|
export declare function newEditorPath(kind: DocumentKind): string;
|
|
89
98
|
/**
|
|
@@ -129,6 +138,7 @@ export interface DocumentSite {
|
|
|
129
138
|
readonly writer: string | undefined;
|
|
130
139
|
readonly citedContext: (target: string) => Promise<ReplyContext | undefined>;
|
|
131
140
|
readonly storedContext: (target: string) => ReplyContext | undefined;
|
|
141
|
+
readonly learnHandles: HandleLearner;
|
|
132
142
|
}
|
|
133
143
|
/** What {@link writeDocument} is asked to write. */
|
|
134
144
|
export interface DocumentWrite {
|
|
@@ -212,19 +222,31 @@ export interface MoveSite {
|
|
|
212
222
|
readonly contentDir: string;
|
|
213
223
|
readonly announce: (change: DocumentChange) => Promise<void>;
|
|
214
224
|
}
|
|
225
|
+
/** What {@link moveDocumentFile} did. */
|
|
226
|
+
export type MoveOutcome = {
|
|
227
|
+
readonly outcome: 'moved';
|
|
228
|
+
readonly document: Document;
|
|
229
|
+
} | {
|
|
230
|
+
readonly outcome: 'refused';
|
|
231
|
+
readonly reason: string;
|
|
232
|
+
};
|
|
215
233
|
/**
|
|
216
234
|
* Move a document into `content/_trash/` or back out of it, the move behind
|
|
217
235
|
* the editor's trash and restore and Micropub's delete and undelete
|
|
218
|
-
* (TASK-167).
|
|
219
|
-
* could not be moved.
|
|
236
|
+
* (TASK-167).
|
|
220
237
|
*
|
|
221
238
|
* The trash mirrors the content tree — `posts/2026-03-04-x.md` becomes
|
|
222
239
|
* `_trash/posts/2026-03-04-x.md` — so restoring is the same move backwards and
|
|
223
240
|
* needs to remember nothing. The index is corrected as soon as the file has
|
|
224
241
|
* landed rather than waiting for the watcher, so the public site stops or
|
|
225
242
|
* starts serving the document with this request (doc-1).
|
|
243
|
+
*
|
|
244
|
+
* A live document may take a trashed one's URL, and its file name with it
|
|
245
|
+
* (TASK-195). So a restore that would land on either is refused, and a trashed
|
|
246
|
+
* file already at the name is kept by numbering the newcomer: the permalink in
|
|
247
|
+
* the front matter, not the file name, is what the document answers at.
|
|
226
248
|
*/
|
|
227
|
-
export declare function moveDocumentFile(site: MoveSite, document: Document, action: 'trash' | 'restore'): Promise<
|
|
249
|
+
export declare function moveDocumentFile(site: MoveSite, document: Document, action: 'trash' | 'restore'): Promise<MoveOutcome>;
|
|
228
250
|
/**
|
|
229
251
|
* A submitted return path, when it is one this admin could have rendered.
|
|
230
252
|
*
|
|
@@ -261,6 +283,11 @@ export interface EditorForm {
|
|
|
261
283
|
author: string;
|
|
262
284
|
/** The post this one replies to, the mf2 `in-reply-to`. Posts only. */
|
|
263
285
|
inReplyTo: string;
|
|
286
|
+
/**
|
|
287
|
+
* Whether the author is going to the event `inReplyTo` names, the mf2
|
|
288
|
+
* `rsvp` (TASK-198), as the file or the form spells it. Posts only.
|
|
289
|
+
*/
|
|
290
|
+
rsvp: string;
|
|
264
291
|
/** The post this one reposts, the mf2 `repost-of` (TASK-169). Posts only. */
|
|
265
292
|
repostOf: string;
|
|
266
293
|
/** The post this one likes, the mf2 `like-of` (TASK-169). Posts only. */
|
|
@@ -274,6 +301,8 @@ export interface EditorForm {
|
|
|
274
301
|
readStatus: string;
|
|
275
302
|
/** What was read, the mf2 `read-of` (TASK-229). Posts only. */
|
|
276
303
|
readOf: ReadOfForm;
|
|
304
|
+
/** When and where the post's event is (TASK-200). Posts only. */
|
|
305
|
+
event: EventForm;
|
|
277
306
|
/** The language it is written in, the `lang` key; empty for the site's. */
|
|
278
307
|
lang: string;
|
|
279
308
|
draft: boolean;
|
|
@@ -345,12 +374,12 @@ export declare function blankForm(kind: DocumentKind, timezone?: string, now?: D
|
|
|
345
374
|
*/
|
|
346
375
|
export declare function formFor(document: Document, timezone: string, location: PostLocation | undefined): EditorForm;
|
|
347
376
|
/**
|
|
348
|
-
* The document of this kind with this slug.
|
|
377
|
+
* The document of this kind with this slug, a live one before a trashed one.
|
|
349
378
|
*
|
|
350
379
|
* The index's slug lookup is across both kinds and is not unique, so a direct
|
|
351
|
-
* hit is only taken when it is of the right kind; otherwise the
|
|
352
|
-
* searched, trash included, because the editor is where a trashed
|
|
353
|
-
* restored from.
|
|
380
|
+
* hit is only taken when it is live and of the right kind; otherwise the
|
|
381
|
+
* listing is searched, trash included, because the editor is where a trashed
|
|
382
|
+
* document is restored from.
|
|
354
383
|
*/
|
|
355
384
|
export declare function findBySlug(store: ContentStore, kind: DocumentKind, slug: string): Document | undefined;
|
|
356
385
|
/** What the listing template shows for one document. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"documents.d.ts","sourceRoot":"","sources":["../../src/admin/documents.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAY1C,OAAO,KAAK,EAAE,QAAQ,EAAmB,YAAY,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"documents.d.ts","sourceRoot":"","sources":["../../src/admin/documents.ts"],"names":[],"mappings":"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"}
|
package/dist/admin/documents.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import { mkdir, readFile, rename, rm } from 'node:fs/promises';
|
|
1
|
+
import { access, mkdir, readFile, rename, rm } from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { CITATION_PROPERTIES, citationText, CITED_ALT_FRONT_MATTER_KEY, citedHost, citesAnImage, PREVIEW_FRONT_MATTER_KEY, previewShown, } from '../content/citation.js';
|
|
4
|
+
import { handleDirectory } from '../content/handles.js';
|
|
4
5
|
import { renderMarkdown } from '../content/markdown.js';
|
|
5
6
|
import { parseDocument } from '../content/parser.js';
|
|
6
7
|
import { PINNED_FRONT_MATTER_KEY, PINNED_POST_LIMIT, pinnedAt } from '../content/pinned.js';
|
|
7
8
|
import { discoverPostType, postLabel, replyTarget } from '../content/post-type.js';
|
|
8
9
|
import { isReadStatus, READ_OF_FRONT_MATTER_KEY, READ_STATUS_FRONT_MATTER_KEY, READ_STATUS_LABELS, READ_STATUSES, readWork, readWorkFrontMatter, } from '../content/read.js';
|
|
10
|
+
import { RSVP_FRONT_MATTER_KEY, RSVP_LABELS, RSVP_VALUES, rsvpValue } from '../content/rsvp.js';
|
|
9
11
|
import { ENCLOSURE_FRONT_MATTER_KEY, enclosureOf, isWebUrl, TRANSCRIPT_TYPES, } from '../content/enclosure.js';
|
|
10
12
|
import { PHOTO_FRONT_MATTER_KEY, photoFrontMatter } from '../content/photo.js';
|
|
11
13
|
import { keptProperties } from '../content/kept-properties.js';
|
|
@@ -39,6 +41,8 @@ import { allowGeolocation } from './headers.js';
|
|
|
39
41
|
import { BLANK_LOCATION_FORM, LOCATION_FIELDS, locationForm, readLocationForm, resolveLocation, } from './location-field.js';
|
|
40
42
|
import { PHOTO_FIELDS, photoChoices, photoRows, photoRowViews, readPhotoForm, resolvePhotos, } from './photo-field.js';
|
|
41
43
|
import { BLANK_READ_OF_FORM, READ_FIELDS, readOfForm, resolveRead, submittedReadOfForm, } from './read-field.js';
|
|
44
|
+
import { BLANK_EVENT_FORM, EVENT_FIELDS, eventForm, eventFrontMatter, resolveEvent, submittedEventForm, } from './event-field.js';
|
|
45
|
+
import { eventOf } from '../content/event.js';
|
|
42
46
|
import { SYNDICATE_TO_FRONT_MATTER_KEY, syndicateToOf, syndicationTargetsReader, } from '../webmention/syndication.js';
|
|
43
47
|
import { shownInFull } from '../webmention/cited-picture.js';
|
|
44
48
|
/**
|
|
@@ -107,6 +111,18 @@ export const PAGE_KIND = {
|
|
|
107
111
|
export function editorPath(kind, slug) {
|
|
108
112
|
return `${kind.basePath}/${encodeURIComponent(slug)}`;
|
|
109
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* The URL of the editor for this document.
|
|
116
|
+
*
|
|
117
|
+
* A trashed document also names its file, because a live document may have
|
|
118
|
+
* taken its slug along with its URL (TASK-195).
|
|
119
|
+
*/
|
|
120
|
+
export function documentEditorPath(kind, document) {
|
|
121
|
+
const address = editorPath(kind, document.slug);
|
|
122
|
+
if (!isTrashedPath(document.path))
|
|
123
|
+
return address;
|
|
124
|
+
return `${address}?${new URLSearchParams({ path: document.path }).toString()}`;
|
|
125
|
+
}
|
|
110
126
|
/** The URL of the editor for a document that does not exist yet. */
|
|
111
127
|
export function newEditorPath(kind) {
|
|
112
128
|
return `${kind.basePath}/new`;
|
|
@@ -185,7 +201,7 @@ export function mountDocumentScreens(app, options) {
|
|
|
185
201
|
}));
|
|
186
202
|
app.post(newEditorPath(kind), async (c) => saveFromForm(c, { kind, render, document: undefined, body: await c.req.parseBody() }));
|
|
187
203
|
app.get(`${kind.basePath}/:slug`, (c) => {
|
|
188
|
-
const document =
|
|
204
|
+
const document = findEdited(c.var.store, kind, c.req.param('slug'), c.req.query('path'));
|
|
189
205
|
if (document === undefined)
|
|
190
206
|
return c.notFound();
|
|
191
207
|
const location = postLocations(c.var.config.dataDir).read(document.permalink);
|
|
@@ -197,7 +213,7 @@ export function mountDocumentScreens(app, options) {
|
|
|
197
213
|
});
|
|
198
214
|
});
|
|
199
215
|
app.post(`${kind.basePath}/:slug`, async (c) => {
|
|
200
|
-
const document =
|
|
216
|
+
const document = findEdited(c.var.store, kind, c.req.param('slug'), c.req.query('path'));
|
|
201
217
|
if (document === undefined)
|
|
202
218
|
return c.notFound();
|
|
203
219
|
const body = await c.req.parseBody();
|
|
@@ -227,9 +243,11 @@ async function saveFromForm(c, options) {
|
|
|
227
243
|
description: text(body['description']).trim(),
|
|
228
244
|
author: text(body['author']).trim(),
|
|
229
245
|
inReplyTo: text(body['in-reply-to']).trim(),
|
|
246
|
+
rsvp: kind.type === 'post' ? text(body[RSVP_FRONT_MATTER_KEY]).trim() : '',
|
|
230
247
|
...citationFields((property) => (kind.type === 'post' ? text(body[property]).trim() : '')),
|
|
231
248
|
readStatus: kind.type === 'post' ? text(body[READ_FIELDS.status]).trim() : '',
|
|
232
249
|
readOf: kind.type === 'post' ? submittedReadOfForm(body) : BLANK_READ_OF_FORM,
|
|
250
|
+
event: kind.type === 'post' ? submittedEventForm(body) : BLANK_EVENT_FORM,
|
|
233
251
|
lang: text(body['lang']).trim(),
|
|
234
252
|
draft: body['draft'] !== undefined,
|
|
235
253
|
visibility: formVisibility(text(body['visibility'])),
|
|
@@ -271,6 +289,7 @@ async function saveFromForm(c, options) {
|
|
|
271
289
|
writer: currentUsername(c),
|
|
272
290
|
citedContext: (target) => c.var.replyContexts.describe(target),
|
|
273
291
|
storedContext: (target) => c.var.replyContexts.read(target),
|
|
292
|
+
learnHandles: c.var.learnHandles,
|
|
274
293
|
}, { kind, document, form, draft });
|
|
275
294
|
if (written.outcome === 'refused')
|
|
276
295
|
return refuse(written);
|
|
@@ -288,7 +307,7 @@ async function saveFromForm(c, options) {
|
|
|
288
307
|
flash(c, 'notice', savedMessage(document, saved, store.now(), (url) => c.var.replyContexts.read(url)));
|
|
289
308
|
if (undescribed.length > 0)
|
|
290
309
|
flash(c, 'warning', missingAltText(undescribed));
|
|
291
|
-
return c.redirect(
|
|
310
|
+
return c.redirect(documentEditorPath(kind, saved), 303);
|
|
292
311
|
}
|
|
293
312
|
/**
|
|
294
313
|
* The write path behind the editor and Micropub (TASK-164): one form in, one
|
|
@@ -315,6 +334,14 @@ export async function writeDocument(site, write) {
|
|
|
315
334
|
if (kind.type === 'post' && form.inReplyTo !== '' && replyTarget(form) === undefined) {
|
|
316
335
|
return refused('In reply to has to be a web address, like https://example.com/a-post/.', 'editor-in-reply-to');
|
|
317
336
|
}
|
|
337
|
+
if (kind.type === 'post' && form.rsvp !== '') {
|
|
338
|
+
if (rsvpValue(form.rsvp) === undefined) {
|
|
339
|
+
return refused(`RSVP is ${RSVP_VALUES.join(', ')}, not ${form.rsvp}.`, 'editor-rsvp');
|
|
340
|
+
}
|
|
341
|
+
if (form.inReplyTo === '') {
|
|
342
|
+
return refused('An RSVP answers an event. Put the event’s address in In reply to.', 'editor-in-reply-to');
|
|
343
|
+
}
|
|
344
|
+
}
|
|
318
345
|
let read;
|
|
319
346
|
if (kind.type === 'post') {
|
|
320
347
|
for (const property of CITATION_PROPERTIES) {
|
|
@@ -381,6 +408,14 @@ export async function writeDocument(site, write) {
|
|
|
381
408
|
return refused('This site publishes no image without alt text. Describe the image this post reposts in its alt text field.', 'editor-cited-alt');
|
|
382
409
|
}
|
|
383
410
|
const timezone = readSiteSettings(contentDir).timezone;
|
|
411
|
+
if (kind.type === 'post') {
|
|
412
|
+
const resolved = resolveEvent(form.event, timezone);
|
|
413
|
+
if ('error' in resolved)
|
|
414
|
+
return refused(resolved.error, resolved.field);
|
|
415
|
+
if (resolved.event !== undefined && form.title === '') {
|
|
416
|
+
return refused('An event needs a name. Put it in Title.', 'editor-title');
|
|
417
|
+
}
|
|
418
|
+
}
|
|
384
419
|
// decision-11: what the file gets is a UTC instant, and an offset-less field
|
|
385
420
|
// is the site's own wall clock rather than the server's.
|
|
386
421
|
const typed = kind.dated ? (form.date === '' ? store.now().toISOString() : form.date) : undefined;
|
|
@@ -449,7 +484,7 @@ export async function writeDocument(site, write) {
|
|
|
449
484
|
...optional('author', chosenAuthor(config.dataDir, form.author, document, writer)),
|
|
450
485
|
...optional('inReplyTo', replyTo(kind, form, document)),
|
|
451
486
|
...optional('activitypub', keptIdentity(document, promised, permalink, config.baseUrl)),
|
|
452
|
-
extra: resolveExtra(kind, document, form, store.now(), media, syndicationTargetsReader(contentDir)()),
|
|
487
|
+
extra: resolveExtra(kind, document, form, store.now(), media, syndicationTargetsReader(contentDir)(), timezone),
|
|
453
488
|
body: form.body,
|
|
454
489
|
};
|
|
455
490
|
// The row for the old path goes first: a rename briefly leaves two rows
|
|
@@ -457,6 +492,7 @@ export async function writeDocument(site, write) {
|
|
|
457
492
|
const renamedFrom = document !== undefined && document.path !== target ? document : undefined;
|
|
458
493
|
if (renamedFrom !== undefined)
|
|
459
494
|
store.remove(renamedFrom.path);
|
|
495
|
+
await site.learnHandles(content.body);
|
|
460
496
|
let saved;
|
|
461
497
|
try {
|
|
462
498
|
saved = await saveDocument({ contentDir, store, path: target, content, timezone });
|
|
@@ -531,6 +567,7 @@ const CITED_SLUGS = {
|
|
|
531
567
|
repost: { prefix: 'reposted', field: 'repostOf' },
|
|
532
568
|
like: { prefix: 'liked', field: 'likeOf' },
|
|
533
569
|
reply: { prefix: 'reply-to', field: 'inReplyTo' },
|
|
570
|
+
rsvp: { prefix: 'rsvp', field: 'inReplyTo' },
|
|
534
571
|
bookmark: { prefix: 'bookmarked', field: 'bookmarkOf' },
|
|
535
572
|
};
|
|
536
573
|
async function typeSlug(kind, form, photos, citedContext) {
|
|
@@ -540,6 +577,7 @@ async function typeSlug(kind, form, photos, citedContext) {
|
|
|
540
577
|
'repost-of': form.repostOf,
|
|
541
578
|
'like-of': form.likeOf,
|
|
542
579
|
'in-reply-to': form.inReplyTo,
|
|
580
|
+
rsvp: form.rsvp,
|
|
543
581
|
'bookmark-of': form.bookmarkOf,
|
|
544
582
|
photo: photos.map((photo) => photo.url),
|
|
545
583
|
});
|
|
@@ -737,7 +775,7 @@ function normalizePermalink(value) {
|
|
|
737
775
|
* the `false` is written, because a key somebody wrote by hand is not the
|
|
738
776
|
* editor's to delete.
|
|
739
777
|
*/
|
|
740
|
-
function resolveExtra(kind, document, form, now, media, declared) {
|
|
778
|
+
function resolveExtra(kind, document, form, now, media, declared, timezone) {
|
|
741
779
|
const extra = { ...(document?.extra ?? {}) };
|
|
742
780
|
if (kind.type === 'post') {
|
|
743
781
|
if (media.recording === undefined)
|
|
@@ -755,6 +793,20 @@ function resolveExtra(kind, document, form, now, media, declared) {
|
|
|
755
793
|
else
|
|
756
794
|
extra[property] = cited;
|
|
757
795
|
}
|
|
796
|
+
const rsvp = rsvpValue(form.rsvp);
|
|
797
|
+
if (rsvp === undefined)
|
|
798
|
+
delete extra[RSVP_FRONT_MATTER_KEY];
|
|
799
|
+
else
|
|
800
|
+
extra[RSVP_FRONT_MATTER_KEY] = rsvp;
|
|
801
|
+
const event = resolveEvent(form.event, timezone);
|
|
802
|
+
if ('event' in event && isOrWasEvent(event.event, document)) {
|
|
803
|
+
for (const [key, value] of Object.entries(eventFrontMatter(event.event))) {
|
|
804
|
+
if (value === undefined)
|
|
805
|
+
delete extra[key];
|
|
806
|
+
else
|
|
807
|
+
extra[key] = value;
|
|
808
|
+
}
|
|
809
|
+
}
|
|
758
810
|
if (form.previewHidden)
|
|
759
811
|
extra[PREVIEW_FRONT_MATTER_KEY] = false;
|
|
760
812
|
else
|
|
@@ -836,6 +888,9 @@ function resolveExtra(kind, document, form, now, media, declared) {
|
|
|
836
888
|
}
|
|
837
889
|
return extra;
|
|
838
890
|
}
|
|
891
|
+
function isOrWasEvent(saved, document) {
|
|
892
|
+
return saved !== undefined || (document !== undefined && eventOf(document.extra) !== undefined);
|
|
893
|
+
}
|
|
839
894
|
/** The editor checkbox that selects one syndication target. */
|
|
840
895
|
function syndicateToField(target) {
|
|
841
896
|
return `${SYNDICATE_TO_FRONT_MATTER_KEY}-${target.id}`;
|
|
@@ -965,7 +1020,7 @@ function renderConflict(c, options) {
|
|
|
965
1020
|
...optional('author', document.author),
|
|
966
1021
|
...optional('inReplyTo', replyTo(kind, form, document)),
|
|
967
1022
|
...optional('activitypub', document.activitypub),
|
|
968
|
-
extra: resolveExtra(kind, document, form, c.var.store.now(), options.media, syndicationTargetsReader(c.var.config.contentDir)()),
|
|
1023
|
+
extra: resolveExtra(kind, document, form, c.var.store.now(), options.media, syndicationTargetsReader(c.var.config.contentDir)(), siteTimezone(c)),
|
|
969
1024
|
body: form.body,
|
|
970
1025
|
});
|
|
971
1026
|
c.status(409);
|
|
@@ -980,8 +1035,8 @@ function renderConflict(c, options) {
|
|
|
980
1035
|
freshHash: conflict.hash,
|
|
981
1036
|
submitted,
|
|
982
1037
|
current: conflict.current,
|
|
983
|
-
editUrl:
|
|
984
|
-
saveUrl:
|
|
1038
|
+
editUrl: documentEditorPath(kind, document),
|
|
1039
|
+
saveUrl: documentEditorPath(kind, document),
|
|
985
1040
|
action: form.draft ? 'save-draft' : 'publish',
|
|
986
1041
|
});
|
|
987
1042
|
}
|
|
@@ -997,35 +1052,50 @@ async function moveDocument(c, options) {
|
|
|
997
1052
|
if (action === 'restore' && !trashed)
|
|
998
1053
|
return backTo(c, options, `It is not in the trash.`);
|
|
999
1054
|
const moved = await moveDocumentFile({ store: c.var.store, contentDir: c.var.config.contentDir, announce: c.var.announce }, document, action);
|
|
1000
|
-
if (moved ===
|
|
1001
|
-
return backTo(c, options,
|
|
1002
|
-
}
|
|
1055
|
+
if (moved.outcome === 'refused')
|
|
1056
|
+
return backTo(c, options, moved.reason);
|
|
1003
1057
|
const label = postLabel(document, (url) => c.var.replyContexts.read(url));
|
|
1004
1058
|
const message = action === 'trash' ? `Moved to the trash: ${label}` : `Restored: ${label}`;
|
|
1005
1059
|
flash(c, 'notice', message);
|
|
1006
1060
|
return c.redirect(returnPath(options.returnTo) ??
|
|
1007
|
-
(action === 'trash' ? kind.basePath :
|
|
1061
|
+
(action === 'trash' ? kind.basePath : documentEditorPath(kind, moved.document)), 303);
|
|
1008
1062
|
}
|
|
1009
1063
|
/**
|
|
1010
1064
|
* Move a document into `content/_trash/` or back out of it, the move behind
|
|
1011
1065
|
* the editor's trash and restore and Micropub's delete and undelete
|
|
1012
|
-
* (TASK-167).
|
|
1013
|
-
* could not be moved.
|
|
1066
|
+
* (TASK-167).
|
|
1014
1067
|
*
|
|
1015
1068
|
* The trash mirrors the content tree — `posts/2026-03-04-x.md` becomes
|
|
1016
1069
|
* `_trash/posts/2026-03-04-x.md` — so restoring is the same move backwards and
|
|
1017
1070
|
* needs to remember nothing. The index is corrected as soon as the file has
|
|
1018
1071
|
* landed rather than waiting for the watcher, so the public site stops or
|
|
1019
1072
|
* starts serving the document with this request (doc-1).
|
|
1073
|
+
*
|
|
1074
|
+
* A live document may take a trashed one's URL, and its file name with it
|
|
1075
|
+
* (TASK-195). So a restore that would land on either is refused, and a trashed
|
|
1076
|
+
* file already at the name is kept by numbering the newcomer: the permalink in
|
|
1077
|
+
* the front matter, not the file name, is what the document answers at.
|
|
1020
1078
|
*/
|
|
1021
1079
|
export async function moveDocumentFile(site, document, action) {
|
|
1022
1080
|
const { store, contentDir } = site;
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1081
|
+
let target;
|
|
1082
|
+
if (action === 'trash') {
|
|
1083
|
+
target = await freeTrashPath(contentDir, document.path);
|
|
1084
|
+
}
|
|
1085
|
+
else {
|
|
1086
|
+
target = document.path
|
|
1026
1087
|
.split('/')
|
|
1027
1088
|
.filter((segment) => segment !== TRASH_DIRECTORY)
|
|
1028
1089
|
.join('/');
|
|
1090
|
+
const holder = store.getByPermalink(document.permalink);
|
|
1091
|
+
if (holder !== undefined && !isTrashedPath(holder.path)) {
|
|
1092
|
+
return refusedMove(`${holder.path} now holds ${document.permalink}, so this cannot go back there. ` +
|
|
1093
|
+
'Change one of their permalinks first.');
|
|
1094
|
+
}
|
|
1095
|
+
if (await exists(path.join(contentDir, ...target.split('/')))) {
|
|
1096
|
+
return refusedMove(`${target} already exists, so this cannot go back there.`);
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1029
1099
|
const from = path.join(contentDir, ...document.path.split('/'));
|
|
1030
1100
|
const to = path.join(contentDir, ...target.split('/'));
|
|
1031
1101
|
let source;
|
|
@@ -1035,9 +1105,13 @@ export async function moveDocumentFile(site, document, action) {
|
|
|
1035
1105
|
await rename(from, to);
|
|
1036
1106
|
}
|
|
1037
1107
|
catch {
|
|
1038
|
-
return
|
|
1108
|
+
return refusedMove(`Could not move ${document.path}. Is the file still there?`);
|
|
1039
1109
|
}
|
|
1040
|
-
const moved = parseDocument(source, {
|
|
1110
|
+
const moved = parseDocument(source, {
|
|
1111
|
+
path: target,
|
|
1112
|
+
type: document.type,
|
|
1113
|
+
handles: handleDirectory(contentDir),
|
|
1114
|
+
});
|
|
1041
1115
|
store.remove(document.path);
|
|
1042
1116
|
store.upsert(moved);
|
|
1043
1117
|
// Trashing takes a post off the public site and restoring puts it back, so
|
|
@@ -1049,12 +1123,32 @@ export async function moveDocumentFile(site, document, action) {
|
|
|
1049
1123
|
next: moved,
|
|
1050
1124
|
origin: 'admin',
|
|
1051
1125
|
});
|
|
1052
|
-
return moved;
|
|
1126
|
+
return { outcome: 'moved', document: moved };
|
|
1127
|
+
}
|
|
1128
|
+
function refusedMove(reason) {
|
|
1129
|
+
return { outcome: 'refused', reason };
|
|
1130
|
+
}
|
|
1131
|
+
async function freeTrashPath(contentDir, relative) {
|
|
1132
|
+
const { dir, name, ext } = path.posix.parse(`${TRASH_DIRECTORY}/${relative}`);
|
|
1133
|
+
for (let suffix = 1;; suffix += 1) {
|
|
1134
|
+
const candidate = `${dir}/${name}${suffix === 1 ? '' : `-${String(suffix)}`}${ext}`;
|
|
1135
|
+
if (!(await exists(path.join(contentDir, ...candidate.split('/')))))
|
|
1136
|
+
return candidate;
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
async function exists(file) {
|
|
1140
|
+
try {
|
|
1141
|
+
await access(file);
|
|
1142
|
+
return true;
|
|
1143
|
+
}
|
|
1144
|
+
catch {
|
|
1145
|
+
return false;
|
|
1146
|
+
}
|
|
1053
1147
|
}
|
|
1054
1148
|
/** Report a move that did not happen and go back where the form came from. */
|
|
1055
1149
|
function backTo(c, options, message) {
|
|
1056
1150
|
flash(c, 'error', message);
|
|
1057
|
-
return c.redirect(returnPath(options.returnTo) ??
|
|
1151
|
+
return c.redirect(returnPath(options.returnTo) ?? documentEditorPath(options.kind, options.document), 303);
|
|
1058
1152
|
}
|
|
1059
1153
|
/**
|
|
1060
1154
|
* A submitted return path, when it is one this admin could have rendered.
|
|
@@ -1130,9 +1224,11 @@ export function blankForm(kind, timezone = DEFAULT_TIMEZONE, now = new Date()) {
|
|
|
1130
1224
|
// {@link authorChoices} is where the default is applied.
|
|
1131
1225
|
author: '',
|
|
1132
1226
|
inReplyTo: '',
|
|
1227
|
+
rsvp: '',
|
|
1133
1228
|
...citationFields(() => ''),
|
|
1134
1229
|
readStatus: '',
|
|
1135
1230
|
readOf: BLANK_READ_OF_FORM,
|
|
1231
|
+
event: BLANK_EVENT_FORM,
|
|
1136
1232
|
lang: '',
|
|
1137
1233
|
draft: false,
|
|
1138
1234
|
visibility: 'public',
|
|
@@ -1173,12 +1269,16 @@ export function formFor(document, timezone, location) {
|
|
|
1173
1269
|
description: document.description ?? '',
|
|
1174
1270
|
author: document.author ?? '',
|
|
1175
1271
|
inReplyTo: document.inReplyTo ?? '',
|
|
1272
|
+
rsvp: document.type === 'post' && typeof document.extra[RSVP_FRONT_MATTER_KEY] === 'string'
|
|
1273
|
+
? document.extra[RSVP_FRONT_MATTER_KEY]
|
|
1274
|
+
: '',
|
|
1176
1275
|
// As the file spells it, so a save writes back what it read.
|
|
1177
1276
|
...citationFields((property) => document.type === 'post' ? citationText(document.extra[property]) : ''),
|
|
1178
1277
|
readStatus: document.type === 'post' && typeof document.extra[READ_STATUS_FRONT_MATTER_KEY] === 'string'
|
|
1179
1278
|
? document.extra[READ_STATUS_FRONT_MATTER_KEY]
|
|
1180
1279
|
: '',
|
|
1181
1280
|
readOf: readOfForm(document.type === 'post' ? readWork(document.extra[READ_OF_FRONT_MATTER_KEY]) : undefined),
|
|
1281
|
+
event: document.type === 'post' ? eventForm(document.extra, timezone) : BLANK_EVENT_FORM,
|
|
1182
1282
|
lang: typeof document.extra[LANG_FRONT_MATTER_KEY] === 'string'
|
|
1183
1283
|
? document.extra[LANG_FRONT_MATTER_KEY]
|
|
1184
1284
|
: '',
|
|
@@ -1255,7 +1355,12 @@ async function renderEditor(c, options) {
|
|
|
1255
1355
|
photoChoices: await photoChoices(c.var.config.contentDir),
|
|
1256
1356
|
locationFields: LOCATION_FIELDS,
|
|
1257
1357
|
...citedPreviews(c, form),
|
|
1358
|
+
rsvpChoices: RSVP_VALUES.map((value) => ({ value, label: RSVP_LABELS[value] })),
|
|
1359
|
+
...(form.rsvp === '' || rsvpValue(form.rsvp) !== undefined
|
|
1360
|
+
? {}
|
|
1361
|
+
: { unrecognizedRsvp: form.rsvp }),
|
|
1258
1362
|
readFields: READ_FIELDS,
|
|
1363
|
+
eventFields: EVENT_FIELDS,
|
|
1259
1364
|
readStatuses: READ_STATUSES.map((value) => ({ value, label: READ_STATUS_LABELS[value] })),
|
|
1260
1365
|
...(form.readStatus === '' || isReadStatus(form.readStatus)
|
|
1261
1366
|
? {}
|
|
@@ -1275,7 +1380,7 @@ async function renderEditor(c, options) {
|
|
|
1275
1380
|
heading: document === undefined
|
|
1276
1381
|
? `Add ${kind.singular}`
|
|
1277
1382
|
: `Edit ${kind.singular}: ${postLabel(document, (url) => c.var.replyContexts.read(url))}`,
|
|
1278
|
-
saveUrl: document === undefined ? newEditorPath(kind) :
|
|
1383
|
+
saveUrl: document === undefined ? newEditorPath(kind) : documentEditorPath(kind, document),
|
|
1279
1384
|
listUrl: kind.basePath,
|
|
1280
1385
|
previewUrl: PREVIEW_PATH,
|
|
1281
1386
|
uploadUrl: UPLOADS_PATH,
|
|
@@ -1319,17 +1424,23 @@ function citedPreviews(c, form) {
|
|
|
1319
1424
|
describesCitedImage: Object.values(cards).some((card) => card.described),
|
|
1320
1425
|
};
|
|
1321
1426
|
}
|
|
1427
|
+
function findEdited(store, kind, slug, file) {
|
|
1428
|
+
if (file === undefined)
|
|
1429
|
+
return findBySlug(store, kind, slug);
|
|
1430
|
+
const document = store.getByPath(file);
|
|
1431
|
+
return document?.type === kind.type && document.slug === slug ? document : undefined;
|
|
1432
|
+
}
|
|
1322
1433
|
/**
|
|
1323
|
-
* The document of this kind with this slug.
|
|
1434
|
+
* The document of this kind with this slug, a live one before a trashed one.
|
|
1324
1435
|
*
|
|
1325
1436
|
* The index's slug lookup is across both kinds and is not unique, so a direct
|
|
1326
|
-
* hit is only taken when it is of the right kind; otherwise the
|
|
1327
|
-
* searched, trash included, because the editor is where a trashed
|
|
1328
|
-
* restored from.
|
|
1437
|
+
* hit is only taken when it is live and of the right kind; otherwise the
|
|
1438
|
+
* listing is searched, trash included, because the editor is where a trashed
|
|
1439
|
+
* document is restored from.
|
|
1329
1440
|
*/
|
|
1330
1441
|
export function findBySlug(store, kind, slug) {
|
|
1331
1442
|
const direct = store.getBySlug(slug);
|
|
1332
|
-
if (direct?.type === kind.type)
|
|
1443
|
+
if (direct?.type === kind.type && !isTrashedPath(direct.path))
|
|
1333
1444
|
return direct;
|
|
1334
1445
|
for (const trashed of [false, true]) {
|
|
1335
1446
|
const found = store
|
|
@@ -1376,7 +1487,7 @@ function listRow(kind, document, now, role, cited) {
|
|
|
1376
1487
|
trashed: isTrashedPath(document.path),
|
|
1377
1488
|
scheduled: scheduledFor(document, now) !== undefined,
|
|
1378
1489
|
hidden: typeof visibilityOf(document) !== 'string',
|
|
1379
|
-
editUrl:
|
|
1490
|
+
editUrl: documentEditorPath(kind, document),
|
|
1380
1491
|
viewUrl: isPublic ? document.permalink : undefined,
|
|
1381
1492
|
role,
|
|
1382
1493
|
};
|