@geekity/cms 0.19.0 → 0.21.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 (168) hide show
  1. package/README.md +3 -0
  2. package/admin/components/admin-bar.njk +4 -3
  3. package/admin/layouts/shell.njk +1 -0
  4. package/admin/pages/documents/editor.njk +34 -0
  5. package/admin/static/admin.css +87 -0
  6. package/admin/static/location.js +38 -0
  7. package/dist/admin/comments.js +3 -1
  8. package/dist/admin/comments.js.map +1 -1
  9. package/dist/admin/documents.d.ts +13 -0
  10. package/dist/admin/documents.d.ts.map +1 -1
  11. package/dist/admin/documents.js +107 -34
  12. package/dist/admin/documents.js.map +1 -1
  13. package/dist/admin/editor-layout.d.ts.map +1 -1
  14. package/dist/admin/editor-layout.js +1 -0
  15. package/dist/admin/editor-layout.js.map +1 -1
  16. package/dist/admin/federation.d.ts +3 -1
  17. package/dist/admin/federation.d.ts.map +1 -1
  18. package/dist/admin/federation.js +6 -4
  19. package/dist/admin/federation.js.map +1 -1
  20. package/dist/admin/headers.d.ts +1 -0
  21. package/dist/admin/headers.d.ts.map +1 -1
  22. package/dist/admin/headers.js +3 -0
  23. package/dist/admin/headers.js.map +1 -1
  24. package/dist/admin/media.d.ts.map +1 -1
  25. package/dist/admin/media.js +3 -0
  26. package/dist/admin/media.js.map +1 -1
  27. package/dist/admin/preview.d.ts.map +1 -1
  28. package/dist/admin/preview.js +1 -1
  29. package/dist/admin/preview.js.map +1 -1
  30. package/dist/admin/routes.js +1 -1
  31. package/dist/admin/routes.js.map +1 -1
  32. package/dist/comments/routes.d.ts.map +1 -1
  33. package/dist/comments/routes.js +1 -0
  34. package/dist/comments/routes.js.map +1 -1
  35. package/dist/comments/submission.d.ts +2 -0
  36. package/dist/comments/submission.d.ts.map +1 -1
  37. package/dist/comments/submission.js +1 -1
  38. package/dist/comments/submission.js.map +1 -1
  39. package/dist/config.d.ts +2 -0
  40. package/dist/config.d.ts.map +1 -1
  41. package/dist/config.js.map +1 -1
  42. package/dist/content/citation.d.ts +18 -0
  43. package/dist/content/citation.d.ts.map +1 -1
  44. package/dist/content/citation.js +33 -0
  45. package/dist/content/citation.js.map +1 -1
  46. package/dist/content/markdown.d.ts +9 -0
  47. package/dist/content/markdown.d.ts.map +1 -1
  48. package/dist/content/markdown.js +37 -1
  49. package/dist/content/markdown.js.map +1 -1
  50. package/dist/content/post-type.d.ts +3 -7
  51. package/dist/content/post-type.d.ts.map +1 -1
  52. package/dist/content/post-type.js +39 -17
  53. package/dist/content/post-type.js.map +1 -1
  54. package/dist/content/slug.d.ts +2 -1
  55. package/dist/content/slug.d.ts.map +1 -1
  56. package/dist/content/slug.js +3 -1
  57. package/dist/content/slug.js.map +1 -1
  58. package/dist/env.d.ts +6 -0
  59. package/dist/env.d.ts.map +1 -1
  60. package/dist/federation/article.d.ts +4 -4
  61. package/dist/federation/article.d.ts.map +1 -1
  62. package/dist/federation/article.js +19 -21
  63. package/dist/federation/article.js.map +1 -1
  64. package/dist/federation/delivery.d.ts +10 -0
  65. package/dist/federation/delivery.d.ts.map +1 -1
  66. package/dist/federation/delivery.js +48 -4
  67. package/dist/federation/delivery.js.map +1 -1
  68. package/dist/federation/federation.d.ts +3 -0
  69. package/dist/federation/federation.d.ts.map +1 -1
  70. package/dist/federation/federation.js.map +1 -1
  71. package/dist/federation/mount.js +1 -0
  72. package/dist/federation/mount.js.map +1 -1
  73. package/dist/federation/relays.d.ts +2 -0
  74. package/dist/federation/relays.d.ts.map +1 -1
  75. package/dist/federation/relays.js +1 -0
  76. package/dist/federation/relays.js.map +1 -1
  77. package/dist/index.d.ts.map +1 -1
  78. package/dist/index.js +22 -3
  79. package/dist/index.js.map +1 -1
  80. package/dist/micropub/content.d.ts +15 -0
  81. package/dist/micropub/content.d.ts.map +1 -0
  82. package/dist/micropub/content.js +254 -0
  83. package/dist/micropub/content.js.map +1 -0
  84. package/dist/micropub/create.d.ts.map +1 -1
  85. package/dist/micropub/create.js +13 -8
  86. package/dist/micropub/create.js.map +1 -1
  87. package/dist/micropub/endpoint.d.ts.map +1 -1
  88. package/dist/micropub/endpoint.js +18 -4
  89. package/dist/micropub/endpoint.js.map +1 -1
  90. package/dist/notifications/comments.d.ts +2 -0
  91. package/dist/notifications/comments.d.ts.map +1 -1
  92. package/dist/notifications/comments.js +1 -1
  93. package/dist/notifications/comments.js.map +1 -1
  94. package/dist/notifications/digest.d.ts +2 -0
  95. package/dist/notifications/digest.d.ts.map +1 -1
  96. package/dist/notifications/digest.js +1 -1
  97. package/dist/notifications/digest.js.map +1 -1
  98. package/dist/web/admin-bar.js +2 -1
  99. package/dist/web/admin-bar.js.map +1 -1
  100. package/dist/web/archive.d.ts +2 -1
  101. package/dist/web/archive.d.ts.map +1 -1
  102. package/dist/web/archive.js +2 -2
  103. package/dist/web/archive.js.map +1 -1
  104. package/dist/web/context.d.ts +13 -6
  105. package/dist/web/context.d.ts.map +1 -1
  106. package/dist/web/context.js +14 -4
  107. package/dist/web/context.js.map +1 -1
  108. package/dist/web/conversation.d.ts +2 -0
  109. package/dist/web/conversation.d.ts.map +1 -1
  110. package/dist/web/conversation.js +1 -1
  111. package/dist/web/conversation.js.map +1 -1
  112. package/dist/web/feed-item.d.ts +26 -3
  113. package/dist/web/feed-item.d.ts.map +1 -1
  114. package/dist/web/feed-item.js +57 -6
  115. package/dist/web/feed-item.js.map +1 -1
  116. package/dist/web/feed-rss.js +3 -3
  117. package/dist/web/feed-rss.js.map +1 -1
  118. package/dist/web/feed-source.d.ts +7 -0
  119. package/dist/web/feed-source.d.ts.map +1 -1
  120. package/dist/web/feed-source.js.map +1 -1
  121. package/dist/web/feeds.d.ts.map +1 -1
  122. package/dist/web/feeds.js +14 -2
  123. package/dist/web/feeds.js.map +1 -1
  124. package/dist/web/negotiate.d.ts +4 -0
  125. package/dist/web/negotiate.d.ts.map +1 -1
  126. package/dist/web/negotiate.js +5 -1
  127. package/dist/web/negotiate.js.map +1 -1
  128. package/dist/web/oembed.d.ts +1 -0
  129. package/dist/web/oembed.d.ts.map +1 -1
  130. package/dist/web/oembed.js +3 -5
  131. package/dist/web/oembed.js.map +1 -1
  132. package/dist/web/render.d.ts.map +1 -1
  133. package/dist/web/render.js +30 -15
  134. package/dist/web/render.js.map +1 -1
  135. package/dist/web/routes.d.ts.map +1 -1
  136. package/dist/web/routes.js +7 -4
  137. package/dist/web/routes.js.map +1 -1
  138. package/dist/web/sanitize.d.ts +10 -0
  139. package/dist/web/sanitize.d.ts.map +1 -1
  140. package/dist/web/sanitize.js +180 -0
  141. package/dist/web/sanitize.js.map +1 -1
  142. package/dist/web/templates.d.ts.map +1 -1
  143. package/dist/web/templates.js +2 -0
  144. package/dist/web/templates.js.map +1 -1
  145. package/dist/webmention/cited-picture.d.ts +36 -0
  146. package/dist/webmention/cited-picture.d.ts.map +1 -0
  147. package/dist/webmention/cited-picture.js +118 -0
  148. package/dist/webmention/cited-picture.js.map +1 -0
  149. package/dist/webmention/fetch-public.d.ts +23 -7
  150. package/dist/webmention/fetch-public.d.ts.map +1 -1
  151. package/dist/webmention/fetch-public.js +6 -2
  152. package/dist/webmention/fetch-public.js.map +1 -1
  153. package/dist/webmention/reply-context.d.ts +17 -8
  154. package/dist/webmention/reply-context.d.ts.map +1 -1
  155. package/dist/webmention/reply-context.js +140 -28
  156. package/dist/webmention/reply-context.js.map +1 -1
  157. package/dist/webmention/reply-contexts.d.ts +13 -2
  158. package/dist/webmention/reply-contexts.d.ts.map +1 -1
  159. package/dist/webmention/reply-contexts.js +82 -6
  160. package/dist/webmention/reply-contexts.js.map +1 -1
  161. package/package.json +3 -2
  162. package/themes/default/README.md +60 -5
  163. package/themes/default/layouts/post.njk +2 -1
  164. package/themes/default/partials/citations.njk +14 -2
  165. package/themes/default/partials/cited-page.njk +21 -4
  166. package/themes/default/partials/reply-context.njk +7 -2
  167. package/themes/default/src/style.css +37 -0
  168. package/themes/default/static/style.css +83 -0
@@ -0,0 +1,118 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { mkdir, readdir, rm, writeFile } from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import sharp from 'sharp';
5
+ import { citedImageAlt, citesAnImage } from '../content/citation.js';
6
+ import { matchesSignature, UPLOAD_MEDIA_TYPES } from '../content/media.js';
7
+ import { stripMetadata } from '../content/metadata/index.js';
8
+ import { generateImageVariants, removeImageVariants } from '../images/variants.js';
9
+ import { UPLOAD_ASSET_PREFIX, UPLOAD_DIRECTORY } from '../web/assets.js';
10
+ import { fetchPublic } from './fetch-public.js';
11
+ export const CITED_PICTURE_DIRECTORY = 'cited';
12
+ export const CITED_PICTURE_PREFIX = `${UPLOAD_ASSET_PREFIX}${CITED_PICTURE_DIRECTORY}/`;
13
+ export const CITED_PICTURE_TIMEOUT_MS = 10_000;
14
+ const IMAGE_EXTENSIONS = ['.png', '.jpg', '.gif', '.webp', '.avif'];
15
+ export async function copyCitedPicture(source, options) {
16
+ const fetched = await fetchPublic(source.url, {
17
+ lookup: options.lookup,
18
+ timeoutMs: options.timeoutMs ?? CITED_PICTURE_TIMEOUT_MS,
19
+ maxBytes: options.config.uploadMaxBytes,
20
+ accept: 'image/avif, image/webp, image/png, image/gif, image/jpeg;q=0.9',
21
+ contentType: { pattern: /^\s*image\//i, name: 'an image' },
22
+ });
23
+ if (!fetched.ok)
24
+ return undefined;
25
+ const extension = IMAGE_EXTENSIONS.find((candidate) => {
26
+ const media = UPLOAD_MEDIA_TYPES.get(candidate);
27
+ return media !== undefined && matchesSignature(media, fetched.body);
28
+ });
29
+ if (extension === undefined)
30
+ return undefined;
31
+ let bytes;
32
+ let size;
33
+ try {
34
+ bytes = stripMetadata(extension, fetched.body).bytes;
35
+ size = await uprightSize(bytes);
36
+ }
37
+ catch {
38
+ return undefined;
39
+ }
40
+ if (size === undefined)
41
+ return undefined;
42
+ const name = `${createHash('sha256').update(bytes).digest('hex').slice(0, 16)}${extension}`;
43
+ const directory = path.join(options.config.contentDir, UPLOAD_DIRECTORY, CITED_PICTURE_DIRECTORY);
44
+ await mkdir(directory, { recursive: true });
45
+ try {
46
+ await writeFile(path.join(directory, name), bytes, { flag: 'wx' });
47
+ }
48
+ catch (error) {
49
+ if (error.code !== 'EEXIST')
50
+ throw error;
51
+ }
52
+ try {
53
+ await generateImageVariants(options.config, `${CITED_PICTURE_DIRECTORY}/${name}`);
54
+ }
55
+ catch (error) {
56
+ const message = error instanceof Error ? error.message : String(error);
57
+ console.warn(`Copied ${name} but could not derive its variants: ${message}`);
58
+ }
59
+ return {
60
+ src: `${CITED_PICTURE_PREFIX}${name}`,
61
+ ...size,
62
+ kind: source.kind,
63
+ ...(source.video === true ? { video: true } : {}),
64
+ };
65
+ }
66
+ /** The size a reader sees: orientations 5 to 8 turn the picture on its side. */
67
+ async function uprightSize(bytes) {
68
+ const metadata = await sharp(bytes).metadata();
69
+ const width = metadata.width;
70
+ const height = metadata.pageHeight ?? metadata.height;
71
+ if (width === undefined || height === undefined)
72
+ return undefined;
73
+ return (metadata.orientation ?? 1) >= 5 ? { width: height, height: width } : { width, height };
74
+ }
75
+ export async function sweepCitedPictures(config, kept) {
76
+ const directory = path.join(config.contentDir, UPLOAD_DIRECTORY, CITED_PICTURE_DIRECTORY);
77
+ let names;
78
+ try {
79
+ names = await readdir(directory);
80
+ }
81
+ catch {
82
+ return;
83
+ }
84
+ for (const name of names) {
85
+ if (kept.has(`${CITED_PICTURE_PREFIX}${name}`))
86
+ continue;
87
+ const source = `${CITED_PICTURE_DIRECTORY}/${name}`;
88
+ await removeImageVariants(config, source);
89
+ await rm(path.join(directory, name), { force: true });
90
+ }
91
+ }
92
+ export function shownInFull(property, picture) {
93
+ return property === 'repost-of' && picture.kind === 'photo';
94
+ }
95
+ export function citedPictureAlt(property, context, document) {
96
+ if (context.picture === undefined || !shownInFull(property, context.picture))
97
+ return '';
98
+ return citesAnImage(context) ? citedImageAlt(document) : (context.name ?? '');
99
+ }
100
+ export function parseCitedPicture(value) {
101
+ if (typeof value !== 'object' || value === null || Array.isArray(value))
102
+ return undefined;
103
+ const fields = value;
104
+ const { src, width, height, kind } = fields;
105
+ if (typeof src !== 'string' ||
106
+ !src.startsWith(CITED_PICTURE_PREFIX) ||
107
+ src.slice(CITED_PICTURE_PREFIX.length).includes('/') ||
108
+ !positiveInteger(width) ||
109
+ !positiveInteger(height) ||
110
+ (kind !== 'photo' && kind !== 'thumbnail')) {
111
+ return undefined;
112
+ }
113
+ return { src, width, height, kind, ...(fields['video'] === true ? { video: true } : {}) };
114
+ }
115
+ function positiveInteger(value) {
116
+ return typeof value === 'number' && Number.isInteger(value) && value > 0;
117
+ }
118
+ //# sourceMappingURL=cited-picture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cited-picture.js","sourceRoot":"","sources":["../../src/webmention/cited-picture.ts"],"names":[],"mappings":"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"}
@@ -15,24 +15,40 @@ export interface FetchPublicOptions {
15
15
  readonly pattern: RegExp;
16
16
  readonly name: string;
17
17
  };
18
+ readonly headersOnly?: RegExp;
18
19
  }
19
- /** What one fetch came to. */
20
- export type PublicFetch = {
21
- readonly ok: true;
22
- /** The URL the body came from, after any redirects. */
20
+ interface PublicResponse {
21
+ /** The URL the response came from, after any redirects. */
23
22
  readonly url: string;
24
23
  /** The response's `Content-Type`. */
25
24
  readonly type: string;
26
25
  /** The response's `Link` header, or `null` when it sent none. */
27
26
  readonly link: string | null;
27
+ }
28
+ export interface PublicBody extends PublicResponse {
29
+ readonly ok: true;
30
+ readonly read: 'body';
28
31
  readonly body: Uint8Array;
29
32
  readonly truncated: boolean;
30
- } | {
33
+ }
34
+ export interface PublicHeaders extends PublicResponse {
35
+ readonly ok: true;
36
+ readonly read: 'headers';
37
+ }
38
+ export interface PublicRefusal {
31
39
  readonly ok: false;
32
40
  readonly reason: string;
33
- };
41
+ }
42
+ /** What one fetch came to. */
43
+ export type PublicFetch = PublicBody | PublicHeaders | PublicRefusal;
34
44
  /** Fetch `target` within the limits `options` sets. */
35
- export declare function fetchPublic(target: string, options: FetchPublicOptions): Promise<PublicFetch>;
45
+ export declare function fetchPublic(target: string, options: FetchPublicOptions & {
46
+ readonly headersOnly: RegExp;
47
+ }): Promise<PublicFetch>;
48
+ export declare function fetchPublic(target: string, options: FetchPublicOptions & {
49
+ readonly headersOnly?: undefined;
50
+ }): Promise<PublicBody | PublicRefusal>;
36
51
  /** An http or https URL with a host, or `undefined`. */
37
52
  export declare function webUrl(value: string): URL | undefined;
53
+ export {};
38
54
  //# sourceMappingURL=fetch-public.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-public.d.ts","sourceRoot":"","sources":["../../src/webmention/fetch-public.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAetD,sCAAsC;AACtC,MAAM,WAAW,kBAAkB;IACjC,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,2DAA2D;IAC3D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,uCAAuC;IACvC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;IAC1C,gCAAgC;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,gFAAgF;IAChF,QAAQ,CAAC,WAAW,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3E;AAED,8BAA8B;AAC9B,MAAM,MAAM,WAAW,GACnB;IACE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAClB,uDAAuD;IACvD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,qCAAqC;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,iEAAiE;IACjE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B,GACD;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpD,uDAAuD;AACvD,wBAAsB,WAAW,CAC/B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,WAAW,CAAC,CA6CtB;AAED,wDAAwD;AACxD,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS,CASrD"}
1
+ {"version":3,"file":"fetch-public.d.ts","sourceRoot":"","sources":["../../src/webmention/fetch-public.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAetD,sCAAsC;AACtC,MAAM,WAAW,kBAAkB;IACjC,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,2DAA2D;IAC3D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,uCAAuC;IACvC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;IAC1C,gCAAgC;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,gFAAgF;IAChF,QAAQ,CAAC,WAAW,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1E,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,UAAU,cAAc;IACtB,2DAA2D;IAC3D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,qCAAqC;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,iEAAiE;IACjE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,UAAW,SAAQ,cAAc;IAChD,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAClB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,aAAc,SAAQ,cAAc;IACnD,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAClB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IACnB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,8BAA8B;AAC9B,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,aAAa,GAAG,aAAa,CAAC;AAErE,uDAAuD;AACvD,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,kBAAkB,GAAG;IAAE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAC7D,OAAO,CAAC,WAAW,CAAC,CAAC;AACxB,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,kBAAkB,GAAG;IAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,CAAA;CAAE,GACjE,OAAO,CAAC,UAAU,GAAG,aAAa,CAAC,CAAC;AAwDvC,wDAAwD;AACxD,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS,CASrD"}
@@ -11,7 +11,6 @@ import { publicHost } from './public-address.js';
11
11
  */
12
12
  /** How many redirects are followed, each one checked like the first. */
13
13
  const MAX_REDIRECTS = 5;
14
- /** Fetch `target` within the limits `options` sets. */
15
14
  export async function fetchPublic(target, options) {
16
15
  const signal = AbortSignal.timeout(options.timeoutMs);
17
16
  let at = target;
@@ -41,6 +40,11 @@ export async function fetchPublic(target, options) {
41
40
  return refuse(`answered ${String(response.status)}`);
42
41
  }
43
42
  const type = response.headers.get('content-type') ?? '';
43
+ const link = response.headers.get('link');
44
+ if (options.headersOnly?.test(type) === true) {
45
+ await response.body?.cancel();
46
+ return { ok: true, read: 'headers', url: url.href, type, link };
47
+ }
44
48
  if (!options.contentType.pattern.test(type)) {
45
49
  await response.body?.cancel();
46
50
  return refuse(`not ${options.contentType.name}`);
@@ -48,7 +52,7 @@ export async function fetchPublic(target, options) {
48
52
  const read = await readWithin(response, options.maxBytes, options.overflow ?? 'refuse');
49
53
  if (read === undefined)
50
54
  return refuse(`larger than ${String(options.maxBytes)} bytes`);
51
- return { ok: true, url: url.href, type, link: response.headers.get('link'), ...read };
55
+ return { ok: true, read: 'body', url: url.href, type, link, ...read };
52
56
  }
53
57
  }
54
58
  catch (thrown) {
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-public.js","sourceRoot":"","sources":["../../src/webmention/fetch-public.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fetch-public.js","sourceRoot":"","sources":["../../src/webmention/fetch-public.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import type { CitedPicture, PictureSource } from './cited-picture.ts';
1
2
  import type { HostLookup } from './public-address.ts';
2
3
  /**
3
4
  * Reply context: what a reply shows of the post it answers (TASK-123).
@@ -30,11 +31,15 @@ export interface ReplyContext {
30
31
  };
31
32
  /** When it says it was published, as an ISO 8601 instant. */
32
33
  readonly published?: string;
34
+ /** The site it is on, its `og:site_name`, kept only when it names no author. */
35
+ readonly site?: string;
36
+ /** Its picture, copied into the site's uploads (TASK-252). */
37
+ readonly picture?: CitedPicture;
33
38
  }
34
- /** What fetching one target came to. */
35
39
  export type ReplyContextFetch = {
36
40
  readonly ok: true;
37
41
  readonly context: ReplyContext;
42
+ readonly picture?: PictureSource;
38
43
  } | {
39
44
  readonly ok: false;
40
45
  readonly reason: string;
@@ -49,13 +54,15 @@ export interface FetchReplyContextOptions {
49
54
  readonly maxBytes?: number | undefined;
50
55
  }
51
56
  /**
52
- * Fetch a page a post cites and read what it says about itself, asking its
53
- * oEmbed endpoint as well when it has no `h-entry`.
57
+ * Fetch a page a post cites and read what it says about itself. A known
58
+ * provider's oEmbed endpoint is asked first, and the page is read only when
59
+ * that names nothing. Any other page is read, and asked about through the
60
+ * oEmbed endpoint it links when it has no `h-entry`.
54
61
  *
55
62
  * Only http and https, only public hosts (every redirect hop is checked, and a
56
63
  * name is refused when any address it resolves to is private), one timeout
57
- * over the whole exchange, the oEmbed request included, no more of a page than
58
- * the byte limit, and no oEmbed answer over it. Nothing throws.
64
+ * over the whole exchange, every oEmbed request included, no more of a page
65
+ * than the byte limit, and no oEmbed answer over it. Nothing throws.
59
66
  */
60
67
  export declare function fetchReplyContext(target: string, options: FetchReplyContextOptions): Promise<ReplyContextFetch>;
61
68
  export interface Oembed {
@@ -64,6 +71,7 @@ export interface Oembed {
64
71
  readonly name: string;
65
72
  readonly url?: string;
66
73
  };
74
+ readonly picture?: PictureSource;
67
75
  }
68
76
  /**
69
77
  * What a target page says about itself, or `undefined` when it says nothing a
@@ -72,9 +80,10 @@ export interface Oembed {
72
80
  * The first `h-entry` when there is one: its name when it has one of its own
73
81
  * (the test Post Type Discovery uses), an excerpt of its text, its author and
74
82
  * its date. A page with no `h-entry` is described by its oEmbed title and
75
- * author when `oembed` holds them, then its `<title>`, `og:title` and
76
- * description metadata. Everything comes out as plain text; the theme escapes
77
- * it like any other string.
83
+ * author when `oembed` holds them, then its `og:title`, `<title>` and
84
+ * description metadata, where a title that is only a site suffix is none.
85
+ * Everything comes out as plain text; the theme escapes it like any other
86
+ * string.
78
87
  */
79
88
  export declare function readReplyContext(html: string, target: string, base?: string, oembed?: Oembed): ReplyContext | undefined;
80
89
  //# sourceMappingURL=reply-context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"reply-context.d.ts","sourceRoot":"","sources":["../../src/webmention/reply-context.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD;;;;;;;;GAQG;AAEH,2DAA2D;AAC3D,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAE/C;;;GAGG;AACH,eAAO,MAAM,uBAAuB,UAAY,CAAC;AAQjD,iDAAiD;AACjD,MAAM,WAAW,YAAY;IAC3B,mFAAmF;IACnF,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,kEAAkE;IAClE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,iEAAiE;IACjE,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACnE,6DAA6D;IAC7D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,wCAAwC;AACxC,MAAM,MAAM,iBAAiB,GACzB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;CAAE,GACrD;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpD,4CAA4C;AAC5C,MAAM,WAAW,wBAAwB;IACvC,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,oDAAoD;IACpD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,mDAAmD;IACnD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACxC;AAED;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,iBAAiB,CAAC,CAuB5B;AAED,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACpE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,MAAe,EACrB,MAAM,CAAC,EAAE,MAAM,GACd,YAAY,GAAG,SAAS,CAG1B"}
1
+ {"version":3,"file":"reply-context.d.ts","sourceRoot":"","sources":["../../src/webmention/reply-context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAMtE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD;;;;;;;;GAQG;AAEH,2DAA2D;AAC3D,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAE/C;;;GAGG;AACH,eAAO,MAAM,uBAAuB,UAAY,CAAC;AAUjD,iDAAiD;AACjD,MAAM,WAAW,YAAY;IAC3B,mFAAmF;IACnF,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,kEAAkE;IAClE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,iEAAiE;IACjE,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACnE,6DAA6D;IAC7D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,gFAAgF;IAChF,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,8DAA8D;IAC9D,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC;CACjC;AAED,MAAM,MAAM,iBAAiB,GACzB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAA;CAAE,GACvF;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpD,4CAA4C;AAC5C,MAAM,WAAW,wBAAwB;IACvC,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,oDAAoD;IACpD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,mDAAmD;IACnD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACxC;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,iBAAiB,CAAC,CAmD5B;AAkFD,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACnE,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;CAClC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,MAAe,EACrB,MAAM,CAAC,EAAE,MAAM,GACd,YAAY,GAAG,SAAS,CAG1B"}
@@ -18,40 +18,133 @@ export const REPLY_CONTEXT_TIMEOUT_MS = 10_000;
18
18
  * read, and an oEmbed answer bigger than this is not read at all.
19
19
  */
20
20
  export const REPLY_CONTEXT_MAX_BYTES = 1_000_000;
21
+ const IMAGE_TYPE = /^\s*image\//i;
21
22
  /** How many words of a target's text a preview keeps. */
22
23
  const EXCERPT_WORDS = 40;
23
24
  /** And how many characters, for a text with few spaces in it. */
24
25
  const EXCERPT_CHARACTERS = 300;
25
26
  /**
26
- * Fetch a page a post cites and read what it says about itself, asking its
27
- * oEmbed endpoint as well when it has no `h-entry`.
27
+ * Fetch a page a post cites and read what it says about itself. A known
28
+ * provider's oEmbed endpoint is asked first, and the page is read only when
29
+ * that names nothing. Any other page is read, and asked about through the
30
+ * oEmbed endpoint it links when it has no `h-entry`.
28
31
  *
29
32
  * Only http and https, only public hosts (every redirect hop is checked, and a
30
33
  * name is refused when any address it resolves to is private), one timeout
31
- * over the whole exchange, the oEmbed request included, no more of a page than
32
- * the byte limit, and no oEmbed answer over it. Nothing throws.
34
+ * over the whole exchange, every oEmbed request included, no more of a page
35
+ * than the byte limit, and no oEmbed answer over it. Nothing throws.
33
36
  */
34
37
  export async function fetchReplyContext(target, options) {
35
- const deadline = Date.now() + (options.timeoutMs ?? REPLY_CONTEXT_TIMEOUT_MS);
36
- const maxBytes = options.maxBytes ?? REPLY_CONTEXT_MAX_BYTES;
37
- const fetched = await fetchPublic(target, {
38
+ const limits = {
38
39
  lookup: options.lookup,
39
- timeoutMs: deadline - Date.now(),
40
- maxBytes,
41
- overflow: 'truncate',
42
- accept: 'text/html, */*;q=0.8',
43
- contentType: { pattern: /^\s*(text\/html|application\/xhtml\+xml)/i, name: 'an HTML page' },
44
- });
45
- if (!fetched.ok)
46
- return fetched;
47
- const root = parseHtml(new TextDecoder().decode(fetched.body));
48
- const entry = fetched.truncated ? undefined : citedEntry(root, fetched.url);
49
- const endpoint = entry === undefined ? oembedEndpoint(root, fetched.url) : undefined;
50
- const oembed = endpoint === undefined
51
- ? undefined
52
- : await fetchOembed(endpoint, { lookup: options.lookup, deadline, maxBytes });
40
+ deadline: Date.now() + (options.timeoutMs ?? REPLY_CONTEXT_TIMEOUT_MS),
41
+ maxBytes: options.maxBytes ?? REPLY_CONTEXT_MAX_BYTES,
42
+ };
43
+ const known = knownEndpoint(target);
44
+ if (known !== undefined) {
45
+ const oembed = withoutSuffix(await fetchOembed(known.endpoint, limits), known.titleSuffix);
46
+ const context = describe(parseHtml(''), undefined, target, oembed);
47
+ if (context !== undefined)
48
+ return described(context, oembed?.picture);
49
+ }
50
+ const timeoutMs = limits.deadline - Date.now();
51
+ const fetched = timeoutMs <= 0
52
+ ? { ok: false, reason: 'timed out' }
53
+ : await fetchPublic(target, {
54
+ lookup: limits.lookup,
55
+ timeoutMs,
56
+ maxBytes: limits.maxBytes,
57
+ overflow: 'truncate',
58
+ accept: 'text/html, */*;q=0.8',
59
+ contentType: {
60
+ pattern: /^\s*(text\/html|application\/xhtml\+xml)/i,
61
+ name: 'an HTML page',
62
+ },
63
+ headersOnly: IMAGE_TYPE,
64
+ });
65
+ if (fetched.ok && fetched.read === 'headers') {
66
+ return described({ url: target }, { url: fetched.url, kind: 'photo' });
67
+ }
68
+ const root = parseHtml(fetched.ok ? new TextDecoder().decode(fetched.body) : '');
69
+ const entry = fetched.ok && !fetched.truncated ? citedEntry(root, fetched.url) : undefined;
70
+ const endpoint = fetched.ok && entry === undefined && known === undefined
71
+ ? oembedEndpoint(root, fetched.url)
72
+ : undefined;
73
+ const oembed = endpoint === undefined ? undefined : await fetchOembed(endpoint, limits);
53
74
  const context = describe(root, entry, target, oembed);
54
- return context === undefined ? refuse('nothing to show') : { ok: true, context };
75
+ if (context !== undefined) {
76
+ return described(context, oembed?.picture ?? (fetched.ok ? pagePicture(root, fetched.url) : undefined));
77
+ }
78
+ return fetched.ok ? refuse('nothing to show') : fetched;
79
+ }
80
+ function described(context, picture) {
81
+ return { ok: true, context, ...(picture === undefined ? {} : { picture }) };
82
+ }
83
+ function pagePicture(root, base) {
84
+ const image = metaOf(root, 'og:image') || metaOf(root, 'twitter:image') || metaOf(root, 'twitter:image:src');
85
+ if (image === '')
86
+ return undefined;
87
+ let url;
88
+ try {
89
+ url = webUrl(new URL(image, base).href);
90
+ }
91
+ catch {
92
+ return undefined;
93
+ }
94
+ if (url === undefined)
95
+ return undefined;
96
+ const video = metaOf(root, 'og:type').toLowerCase().startsWith('video') ||
97
+ metaOf(root, 'twitter:card').toLowerCase() === 'player';
98
+ return { url: url.href, kind: 'thumbnail', ...(video ? { video: true } : {}) };
99
+ }
100
+ /**
101
+ * Providers whose JSON oEmbed endpoint is known, asked before their page:
102
+ * YouTube, TikTok, Reddit and Giphy serve a server a generic or slow page, or
103
+ * refuse it, while their endpoints answer (decision-19).
104
+ */
105
+ const KNOWN_OEMBED_PROVIDERS = [
106
+ {
107
+ hosts: ['youtube.com', 'www.youtube.com', 'm.youtube.com'],
108
+ path: /^\/(watch\?(.*&)?v=[\w-]+|shorts\/[\w-]+\/?(\?|$))/,
109
+ endpoint: 'https://www.youtube.com/oembed',
110
+ },
111
+ { hosts: ['youtu.be'], path: /^\/[\w-]+\/?(\?|$)/, endpoint: 'https://www.youtube.com/oembed' },
112
+ {
113
+ hosts: ['tiktok.com', 'www.tiktok.com'],
114
+ path: /^\/@[^/]+\/video\/\d+/,
115
+ endpoint: 'https://www.tiktok.com/oembed',
116
+ },
117
+ {
118
+ hosts: ['reddit.com', 'www.reddit.com'],
119
+ path: /^\/r\/[^/]+\/comments\//,
120
+ endpoint: 'https://www.reddit.com/oembed',
121
+ },
122
+ {
123
+ hosts: ['giphy.com', 'www.giphy.com'],
124
+ path: /^\/gifs\/[^/?]+/,
125
+ endpoint: 'https://giphy.com/services/oembed',
126
+ titleSuffix: ' - Find & Share on GIPHY',
127
+ },
128
+ ];
129
+ function knownEndpoint(target) {
130
+ const url = webUrl(target);
131
+ if (url === undefined)
132
+ return undefined;
133
+ const provider = KNOWN_OEMBED_PROVIDERS.find(({ hosts, path }) => hosts.includes(url.hostname) && path.test(url.pathname + url.search));
134
+ if (provider === undefined)
135
+ return undefined;
136
+ const endpoint = new URL(provider.endpoint);
137
+ endpoint.searchParams.set('format', 'json');
138
+ endpoint.searchParams.set('url', target);
139
+ return { endpoint: endpoint.href, titleSuffix: provider.titleSuffix };
140
+ }
141
+ function withoutSuffix(oembed, suffix) {
142
+ if (oembed?.title === undefined || suffix === undefined || !oembed.title.endsWith(suffix)) {
143
+ return oembed;
144
+ }
145
+ const title = oembed.title.slice(0, -suffix.length).trim();
146
+ const { title: _title, ...rest } = oembed;
147
+ return title === '' ? rest : { ...rest, title };
55
148
  }
56
149
  /**
57
150
  * What a target page says about itself, or `undefined` when it says nothing a
@@ -60,9 +153,10 @@ export async function fetchReplyContext(target, options) {
60
153
  * The first `h-entry` when there is one: its name when it has one of its own
61
154
  * (the test Post Type Discovery uses), an excerpt of its text, its author and
62
155
  * its date. A page with no `h-entry` is described by its oEmbed title and
63
- * author when `oembed` holds them, then its `<title>`, `og:title` and
64
- * description metadata. Everything comes out as plain text; the theme escapes
65
- * it like any other string.
156
+ * author when `oembed` holds them, then its `og:title`, `<title>` and
157
+ * description metadata, where a title that is only a site suffix is none.
158
+ * Everything comes out as plain text; the theme escapes it like any other
159
+ * string.
66
160
  */
67
161
  export function readReplyContext(html, target, base = target, oembed) {
68
162
  const root = parseHtml(html);
@@ -89,11 +183,12 @@ function describe(root, entry, target, oembed) {
89
183
  },
90
184
  }),
91
185
  ...(entry.published === null ? {} : { published: entry.published }),
186
+ ...(authorName === '' ? siteOf(root) : {}),
92
187
  };
93
188
  }
94
189
  const name = withoutDirectionControls(oembed?.title) ||
95
- withoutDirectionControls(titleOf(root)) ||
96
- withoutDirectionControls(metaOf(root, 'og:title'));
190
+ pageTitle(metaOf(root, 'og:title')) ||
191
+ pageTitle(titleOf(root));
97
192
  const text = excerpt(withoutDirectionControls(metaOf(root, 'description')) ||
98
193
  withoutDirectionControls(metaOf(root, 'og:description')));
99
194
  const authorName = withoutDirectionControls(oembed?.author?.name);
@@ -104,15 +199,23 @@ function describe(root, entry, target, oembed) {
104
199
  url: target,
105
200
  ...(name === '' ? {} : { name }),
106
201
  ...(text === '' ? {} : { text }),
107
- ...(author === undefined ? {} : { author }),
202
+ ...(author === undefined ? siteOf(root) : { author }),
108
203
  };
109
204
  }
205
+ function siteOf(root) {
206
+ const site = withoutDirectionControls(metaOf(root, 'og:site_name'));
207
+ return site === '' ? {} : { site };
208
+ }
110
209
  function withoutDirectionControls(text) {
111
210
  return (text ?? '')
112
211
  .replace(/\p{Bidi_Control}/gu, '')
113
212
  .replace(/\s+/g, ' ')
114
213
  .trim();
115
214
  }
215
+ function pageTitle(text) {
216
+ const title = withoutDirectionControls(text);
217
+ return /^[-–—|·•:]\s/u.test(title) ? '' : title;
218
+ }
116
219
  function oembedEndpoint(root, base) {
117
220
  for (const element of elementsIn(root)) {
118
221
  if (element.name !== 'link')
@@ -161,8 +264,17 @@ async function fetchOembed(endpoint, limits) {
161
264
  const title = plainText(fields['title']);
162
265
  const authorName = plainText(fields['author_name']);
163
266
  const authorUrl = webUrl(plainText(fields['author_url']) ?? '');
267
+ const type = plainText(fields['type']);
268
+ const photo = type === 'photo' ? webUrl(plainText(fields['url']) ?? '') : undefined;
269
+ const thumbnail = webUrl(plainText(fields['thumbnail_url']) ?? '');
270
+ const picture = photo !== undefined
271
+ ? { url: photo.href, kind: 'photo' }
272
+ : thumbnail !== undefined
273
+ ? { url: thumbnail.href, kind: 'thumbnail', ...(type === 'video' ? { video: true } : {}) }
274
+ : undefined;
164
275
  return {
165
276
  ...(title === undefined ? {} : { title }),
277
+ ...(picture === undefined ? {} : { picture }),
166
278
  ...(authorName === undefined
167
279
  ? {}
168
280
  : {
@@ -1 +1 @@
1
- {"version":3,"file":"reply-context.js","sourceRoot":"","sources":["../../src/webmention/reply-context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reply-context.js","sourceRoot":"","sources":["../../src/webmention/reply-context.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import type { ContentStore } from '../content/store.ts';
2
2
  import type { DocumentChange } from '../content/sync.ts';
3
+ import type { CitedPictureConfig } from './cited-picture.ts';
3
4
  import type { HostLookup } from './public-address.ts';
4
5
  import type { ReplyContext } from './reply-context.ts';
5
6
  /**
@@ -8,6 +9,7 @@ import type { ReplyContext } from './reply-context.ts';
8
9
  * (decision-19). Eleventy reads it as the `replyContexts` global.
9
10
  */
10
11
  export declare const REPLY_CONTEXTS_FILE = "_data/replyContexts.json";
12
+ export declare const CITED_SLUG_TIMEOUT_MS = 3000;
11
13
  /** Where the service reports a target it could not read. */
12
14
  export interface ReplyContextLogger {
13
15
  warn(message: string): void;
@@ -16,12 +18,14 @@ export interface ReplyContextLogger {
16
18
  export interface CreateReplyContextServiceOptions {
17
19
  /** The index, asked which targets are still cited. */
18
20
  readonly store: ContentStore;
19
- /** Where the file lives. */
20
- readonly contentDir: string;
21
+ /** Where the file and the copied pictures live, and the limit a picture is held to. */
22
+ readonly config: CitedPictureConfig;
21
23
  /** How host names are resolved before a target is fetched. */
22
24
  readonly lookup: HostLookup;
23
25
  /** Defaults to `console`. */
24
26
  readonly logger?: ReplyContextLogger | undefined;
27
+ /** Told each time a target's context is stored, with the one it replaced. */
28
+ readonly onStored?: ((target: string, previous: ReplyContext | undefined) => void) | undefined;
25
29
  }
26
30
  /**
27
31
  * Keeps the stored contexts in step with the posts that cite: a reply's
@@ -43,6 +47,13 @@ export interface ReplyContextService {
43
47
  * Queued like {@link ReplyContextService.handle}.
44
48
  */
45
49
  catchUp(): void;
50
+ /**
51
+ * The context a new post can be named after: the stored one, else one fetch
52
+ * within {@link CITED_SLUG_TIMEOUT_MS} that is stored, so the save's own
53
+ * {@link ReplyContextService.handle} does not fetch it again (TASK-250).
54
+ * `undefined` when the target could not be read in time.
55
+ */
56
+ describe(target: string): Promise<ReplyContext | undefined>;
46
57
  /** The stored context for a target, from the file. Never touches the network. */
47
58
  read(target: string): ReplyContext | undefined;
48
59
  /** Resolve once everything queued has finished, however it finished. */