@geekity/cms 0.17.0 → 0.19.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 (297) hide show
  1. package/README.md +163 -50
  2. package/admin/components/public-admin-bar.njk +3 -1
  3. package/admin/pages/documents/editor.njk +286 -158
  4. package/admin/pages/documents/list.njk +2 -0
  5. package/admin/pages/indieauth/consent.njk +4 -0
  6. package/admin/pages/settings/privacy.njk +37 -0
  7. package/admin/pages/users/apps.njk +109 -3
  8. package/admin/static/admin.css +37 -14
  9. package/dist/admin/documents.d.ts +34 -4
  10. package/dist/admin/documents.d.ts.map +1 -1
  11. package/dist/admin/documents.js +161 -23
  12. package/dist/admin/documents.js.map +1 -1
  13. package/dist/admin/editor-layout.d.ts +13 -0
  14. package/dist/admin/editor-layout.d.ts.map +1 -0
  15. package/dist/admin/editor-layout.js +61 -0
  16. package/dist/admin/editor-layout.js.map +1 -0
  17. package/dist/admin/enclosure-field.d.ts +2 -3
  18. package/dist/admin/enclosure-field.d.ts.map +1 -1
  19. package/dist/admin/enclosure-field.js +27 -7
  20. package/dist/admin/enclosure-field.js.map +1 -1
  21. package/dist/admin/index.d.ts +1 -0
  22. package/dist/admin/index.d.ts.map +1 -1
  23. package/dist/admin/index.js +1 -0
  24. package/dist/admin/index.js.map +1 -1
  25. package/dist/admin/location-field.d.ts +27 -0
  26. package/dist/admin/location-field.d.ts.map +1 -0
  27. package/dist/admin/location-field.js +98 -0
  28. package/dist/admin/location-field.js.map +1 -0
  29. package/dist/admin/menu.d.ts.map +1 -1
  30. package/dist/admin/menu.js +1 -0
  31. package/dist/admin/menu.js.map +1 -1
  32. package/dist/admin/photo-field.d.ts +2 -3
  33. package/dist/admin/photo-field.d.ts.map +1 -1
  34. package/dist/admin/photo-field.js +4 -2
  35. package/dist/admin/photo-field.js.map +1 -1
  36. package/dist/admin/preview.d.ts.map +1 -1
  37. package/dist/admin/preview.js +18 -5
  38. package/dist/admin/preview.js.map +1 -1
  39. package/dist/admin/read-field.d.ts +22 -0
  40. package/dist/admin/read-field.d.ts.map +1 -0
  41. package/dist/admin/read-field.js +61 -0
  42. package/dist/admin/read-field.js.map +1 -0
  43. package/dist/admin/settings-page.d.ts +3 -3
  44. package/dist/admin/settings-page.js +2 -2
  45. package/dist/admin/settings-pages.d.ts +2 -2
  46. package/dist/admin/settings-pages.d.ts.map +1 -1
  47. package/dist/admin/settings-pages.js +4 -2
  48. package/dist/admin/settings-pages.js.map +1 -1
  49. package/dist/admin/settings-privacy.d.ts +3 -0
  50. package/dist/admin/settings-privacy.d.ts.map +1 -0
  51. package/dist/admin/settings-privacy.js +10 -0
  52. package/dist/admin/settings-privacy.js.map +1 -0
  53. package/dist/admin/settings-reading.js +2 -2
  54. package/dist/admin/settings-reading.js.map +1 -1
  55. package/dist/admin/settings.d.ts +18 -2
  56. package/dist/admin/settings.d.ts.map +1 -1
  57. package/dist/admin/settings.js +27 -0
  58. package/dist/admin/settings.js.map +1 -1
  59. package/dist/admin/templates.d.ts +1 -0
  60. package/dist/admin/templates.d.ts.map +1 -1
  61. package/dist/admin/templates.js +1 -0
  62. package/dist/admin/templates.js.map +1 -1
  63. package/dist/admin/uploads.d.ts.map +1 -1
  64. package/dist/admin/uploads.js +14 -1
  65. package/dist/admin/uploads.js.map +1 -1
  66. package/dist/cli.d.ts +1 -1
  67. package/dist/cli.d.ts.map +1 -1
  68. package/dist/cli.js +34 -0
  69. package/dist/cli.js.map +1 -1
  70. package/dist/comments/routes.js +2 -2
  71. package/dist/comments/routes.js.map +1 -1
  72. package/dist/contact/routes.js +2 -2
  73. package/dist/contact/routes.js.map +1 -1
  74. package/dist/content/kept-properties.d.ts +5 -0
  75. package/dist/content/kept-properties.d.ts.map +1 -0
  76. package/dist/content/kept-properties.js +12 -0
  77. package/dist/content/kept-properties.js.map +1 -0
  78. package/dist/content/location.d.ts +62 -0
  79. package/dist/content/location.d.ts.map +1 -0
  80. package/dist/content/location.js +240 -0
  81. package/dist/content/location.js.map +1 -0
  82. package/dist/content/locations.d.ts +6 -0
  83. package/dist/content/locations.d.ts.map +1 -0
  84. package/dist/content/locations.js +7 -0
  85. package/dist/content/locations.js.map +1 -0
  86. package/dist/content/metadata/gif.d.ts +3 -0
  87. package/dist/content/metadata/gif.d.ts.map +1 -0
  88. package/dist/content/metadata/gif.js +65 -0
  89. package/dist/content/metadata/gif.js.map +1 -0
  90. package/dist/content/metadata/index.d.ts +6 -0
  91. package/dist/content/metadata/index.d.ts.map +1 -0
  92. package/dist/content/metadata/index.js +24 -0
  93. package/dist/content/metadata/index.js.map +1 -0
  94. package/dist/content/metadata/isobmff.d.ts +22 -0
  95. package/dist/content/metadata/isobmff.d.ts.map +1 -0
  96. package/dist/content/metadata/isobmff.js +215 -0
  97. package/dist/content/metadata/isobmff.js.map +1 -0
  98. package/dist/content/metadata/jpeg.d.ts +3 -0
  99. package/dist/content/metadata/jpeg.d.ts.map +1 -0
  100. package/dist/content/metadata/jpeg.js +117 -0
  101. package/dist/content/metadata/jpeg.js.map +1 -0
  102. package/dist/content/metadata/png.d.ts +3 -0
  103. package/dist/content/metadata/png.d.ts.map +1 -0
  104. package/dist/content/metadata/png.js +74 -0
  105. package/dist/content/metadata/png.js.map +1 -0
  106. package/dist/content/metadata/shared.d.ts +17 -0
  107. package/dist/content/metadata/shared.d.ts.map +1 -0
  108. package/dist/content/metadata/shared.js +42 -0
  109. package/dist/content/metadata/shared.js.map +1 -0
  110. package/dist/content/metadata/sweep.d.ts +14 -0
  111. package/dist/content/metadata/sweep.d.ts.map +1 -0
  112. package/dist/content/metadata/sweep.js +54 -0
  113. package/dist/content/metadata/sweep.js.map +1 -0
  114. package/dist/content/metadata/tiff.d.ts +7 -0
  115. package/dist/content/metadata/tiff.d.ts.map +1 -0
  116. package/dist/content/metadata/tiff.js +56 -0
  117. package/dist/content/metadata/tiff.js.map +1 -0
  118. package/dist/content/metadata/webp.d.ts +3 -0
  119. package/dist/content/metadata/webp.d.ts.map +1 -0
  120. package/dist/content/metadata/webp.js +67 -0
  121. package/dist/content/metadata/webp.js.map +1 -0
  122. package/dist/content/permalink-file.d.ts +7 -0
  123. package/dist/content/permalink-file.d.ts.map +1 -0
  124. package/dist/content/permalink-file.js +77 -0
  125. package/dist/content/permalink-file.js.map +1 -0
  126. package/dist/content/post-type.d.ts +4 -2
  127. package/dist/content/post-type.d.ts.map +1 -1
  128. package/dist/content/post-type.js +9 -1
  129. package/dist/content/post-type.js.map +1 -1
  130. package/dist/content/read.d.ts +22 -0
  131. package/dist/content/read.d.ts.map +1 -0
  132. package/dist/content/read.js +67 -0
  133. package/dist/content/read.js.map +1 -0
  134. package/dist/content/store.d.ts +4 -4
  135. package/dist/content/store.d.ts.map +1 -1
  136. package/dist/content/store.js +19 -39
  137. package/dist/content/store.js.map +1 -1
  138. package/dist/content/sync.d.ts.map +1 -1
  139. package/dist/content/sync.js +3 -13
  140. package/dist/content/sync.js.map +1 -1
  141. package/dist/content/visibility.d.ts +11 -0
  142. package/dist/content/visibility.d.ts.map +1 -0
  143. package/dist/content/visibility.js +14 -0
  144. package/dist/content/visibility.js.map +1 -0
  145. package/dist/federation/article.d.ts +4 -3
  146. package/dist/federation/article.d.ts.map +1 -1
  147. package/dist/federation/article.js +66 -20
  148. package/dist/federation/article.js.map +1 -1
  149. package/dist/federation/citations.d.ts +7 -6
  150. package/dist/federation/citations.d.ts.map +1 -1
  151. package/dist/federation/citations.js +44 -28
  152. package/dist/federation/citations.js.map +1 -1
  153. package/dist/federation/delivery.d.ts +3 -1
  154. package/dist/federation/delivery.d.ts.map +1 -1
  155. package/dist/federation/delivery.js +29 -21
  156. package/dist/federation/delivery.js.map +1 -1
  157. package/dist/federation/mount.d.ts.map +1 -1
  158. package/dist/federation/mount.js +3 -1
  159. package/dist/federation/mount.js.map +1 -1
  160. package/dist/index.d.ts +6 -5
  161. package/dist/index.d.ts.map +1 -1
  162. package/dist/index.js +5 -1
  163. package/dist/index.js.map +1 -1
  164. package/dist/indexnow.js +2 -2
  165. package/dist/indexnow.js.map +1 -1
  166. package/dist/indieauth/activity-log.d.ts +2 -0
  167. package/dist/indieauth/activity-log.d.ts.map +1 -1
  168. package/dist/indieauth/activity-log.js +12 -2
  169. package/dist/indieauth/activity-log.js.map +1 -1
  170. package/dist/indieauth/app-activity.js +5 -1
  171. package/dist/indieauth/app-activity.js.map +1 -1
  172. package/dist/indieauth/bearer.d.ts +10 -6
  173. package/dist/indieauth/bearer.d.ts.map +1 -1
  174. package/dist/indieauth/bearer.js +28 -25
  175. package/dist/indieauth/bearer.js.map +1 -1
  176. package/dist/indieauth/client-id.d.ts +10 -0
  177. package/dist/indieauth/client-id.d.ts.map +1 -0
  178. package/dist/indieauth/client-id.js +30 -0
  179. package/dist/indieauth/client-id.js.map +1 -0
  180. package/dist/indieauth/connected-apps.d.ts +4 -0
  181. package/dist/indieauth/connected-apps.d.ts.map +1 -1
  182. package/dist/indieauth/connected-apps.js +149 -20
  183. package/dist/indieauth/connected-apps.js.map +1 -1
  184. package/dist/indieauth/consent.d.ts.map +1 -1
  185. package/dist/indieauth/consent.js +5 -1
  186. package/dist/indieauth/consent.js.map +1 -1
  187. package/dist/indieauth/grants.d.ts +2 -7
  188. package/dist/indieauth/grants.d.ts.map +1 -1
  189. package/dist/indieauth/grants.js.map +1 -1
  190. package/dist/indieauth/redeem.d.ts.map +1 -1
  191. package/dist/indieauth/redeem.js +10 -5
  192. package/dist/indieauth/redeem.js.map +1 -1
  193. package/dist/indieauth/request.d.ts +8 -4
  194. package/dist/indieauth/request.d.ts.map +1 -1
  195. package/dist/indieauth/request.js +29 -30
  196. package/dist/indieauth/request.js.map +1 -1
  197. package/dist/indieauth/token.js +2 -2
  198. package/dist/indieauth/token.js.map +1 -1
  199. package/dist/indieauth/tokens.d.ts +28 -7
  200. package/dist/indieauth/tokens.d.ts.map +1 -1
  201. package/dist/indieauth/tokens.js +26 -5
  202. package/dist/indieauth/tokens.js.map +1 -1
  203. package/dist/micropub/create.d.ts +26 -0
  204. package/dist/micropub/create.d.ts.map +1 -1
  205. package/dist/micropub/create.js +158 -13
  206. package/dist/micropub/create.js.map +1 -1
  207. package/dist/micropub/endpoint.d.ts +4 -5
  208. package/dist/micropub/endpoint.d.ts.map +1 -1
  209. package/dist/micropub/endpoint.js +83 -25
  210. package/dist/micropub/endpoint.js.map +1 -1
  211. package/dist/micropub/media.d.ts +6 -2
  212. package/dist/micropub/media.d.ts.map +1 -1
  213. package/dist/micropub/media.js +43 -37
  214. package/dist/micropub/media.js.map +1 -1
  215. package/dist/micropub/update.d.ts +13 -3
  216. package/dist/micropub/update.d.ts.map +1 -1
  217. package/dist/micropub/update.js +60 -7
  218. package/dist/micropub/update.js.map +1 -1
  219. package/dist/notify.d.ts.map +1 -1
  220. package/dist/notify.js +2 -5
  221. package/dist/notify.js.map +1 -1
  222. package/dist/web/absolute-urls.d.ts +2 -0
  223. package/dist/web/absolute-urls.d.ts.map +1 -0
  224. package/dist/web/absolute-urls.js +22 -0
  225. package/dist/web/absolute-urls.js.map +1 -0
  226. package/dist/web/admin-bar.d.ts.map +1 -1
  227. package/dist/web/admin-bar.js +25 -0
  228. package/dist/web/admin-bar.js.map +1 -1
  229. package/dist/web/context.d.ts +29 -1
  230. package/dist/web/context.d.ts.map +1 -1
  231. package/dist/web/context.js +33 -0
  232. package/dist/web/context.js.map +1 -1
  233. package/dist/web/conversation.d.ts.map +1 -1
  234. package/dist/web/conversation.js +5 -4
  235. package/dist/web/conversation.js.map +1 -1
  236. package/dist/web/documents.d.ts +34 -10
  237. package/dist/web/documents.d.ts.map +1 -1
  238. package/dist/web/documents.js +41 -15
  239. package/dist/web/documents.js.map +1 -1
  240. package/dist/web/feed-item.d.ts +25 -6
  241. package/dist/web/feed-item.d.ts.map +1 -1
  242. package/dist/web/feed-item.js +31 -7
  243. package/dist/web/feed-item.js.map +1 -1
  244. package/dist/web/feed-json.d.ts +3 -1
  245. package/dist/web/feed-json.d.ts.map +1 -1
  246. package/dist/web/feed-json.js +2 -0
  247. package/dist/web/feed-json.js.map +1 -1
  248. package/dist/web/feed-source.d.ts +6 -0
  249. package/dist/web/feed-source.d.ts.map +1 -1
  250. package/dist/web/feed-source.js.map +1 -1
  251. package/dist/web/feeds.d.ts.map +1 -1
  252. package/dist/web/feeds.js +2 -0
  253. package/dist/web/feeds.js.map +1 -1
  254. package/dist/web/html-attributes.d.ts +3 -0
  255. package/dist/web/html-attributes.d.ts.map +1 -0
  256. package/dist/web/html-attributes.js +15 -0
  257. package/dist/web/html-attributes.js.map +1 -0
  258. package/dist/web/index.d.ts +1 -1
  259. package/dist/web/index.d.ts.map +1 -1
  260. package/dist/web/index.js +1 -1
  261. package/dist/web/index.js.map +1 -1
  262. package/dist/web/negotiate.d.ts +2 -0
  263. package/dist/web/negotiate.d.ts.map +1 -1
  264. package/dist/web/negotiate.js +2 -1
  265. package/dist/web/negotiate.js.map +1 -1
  266. package/dist/web/render.d.ts +13 -4
  267. package/dist/web/render.d.ts.map +1 -1
  268. package/dist/web/render.js +25 -12
  269. package/dist/web/render.js.map +1 -1
  270. package/dist/web/routes.d.ts.map +1 -1
  271. package/dist/web/routes.js +26 -11
  272. package/dist/web/routes.js.map +1 -1
  273. package/dist/webmention/fetch-public.d.ts +3 -1
  274. package/dist/webmention/fetch-public.d.ts.map +1 -1
  275. package/dist/webmention/fetch-public.js +17 -11
  276. package/dist/webmention/fetch-public.js.map +1 -1
  277. package/dist/webmention/reply-context.d.ts +18 -5
  278. package/dist/webmention/reply-context.d.ts.map +1 -1
  279. package/dist/webmention/reply-context.js +118 -19
  280. package/dist/webmention/reply-context.js.map +1 -1
  281. package/dist/webmention/reply-contexts.d.ts +17 -14
  282. package/dist/webmention/reply-contexts.d.ts.map +1 -1
  283. package/dist/webmention/reply-contexts.js +32 -21
  284. package/dist/webmention/reply-contexts.js.map +1 -1
  285. package/dist/webmention/service.d.ts.map +1 -1
  286. package/dist/webmention/service.js +7 -2
  287. package/dist/webmention/service.js.map +1 -1
  288. package/package.json +9 -9
  289. package/themes/default/README.md +45 -7
  290. package/themes/default/layouts/base.njk +2 -0
  291. package/themes/default/layouts/post.njk +12 -7
  292. package/themes/default/partials/citations.njk +12 -3
  293. package/themes/default/partials/cited-page.njk +41 -0
  294. package/themes/default/partials/location.njk +12 -0
  295. package/themes/default/partials/post-list.njk +10 -5
  296. package/themes/default/partials/read.njk +5 -0
  297. package/themes/default/partials/reply-context.njk +2 -9
@@ -0,0 +1,215 @@
1
+ import { ascii, fourcc, sameBytes, unique, UnreadableMetadataError, view } from './shared.js';
2
+ /**
3
+ * The boxes laid end to end between `start` and `end`. A box whose size runs
4
+ * past `end` is taken as cut short there, and a size of zero runs to `end`,
5
+ * as the format says.
6
+ */
7
+ function boxes(bytes, start, end) {
8
+ const data = view(bytes);
9
+ const found = [];
10
+ for (let at = start; at + 8 <= end;) {
11
+ let size = data.getUint32(at);
12
+ let body = at + 8;
13
+ if (size === 1) {
14
+ if (at + 16 > end)
15
+ break;
16
+ size = Number(data.getBigUint64(at + 8));
17
+ body = at + 16;
18
+ }
19
+ else if (size === 0) {
20
+ size = end - at;
21
+ }
22
+ if (size < body - at)
23
+ break;
24
+ const boxEnd = Math.min(end, at + size);
25
+ found.push({ type: fourcc(bytes, at + 4), start: at, body, end: boxEnd });
26
+ at = boxEnd;
27
+ }
28
+ return found;
29
+ }
30
+ const MOVIE_CONTAINERS = new Set(['moov', 'trak', 'mdia', 'minf']);
31
+ const MOVIE_LABELS = {
32
+ udta: 'user data (location, camera)',
33
+ meta: 'metadata (location, camera)',
34
+ uuid: 'XMP',
35
+ XMP_: 'XMP',
36
+ };
37
+ /**
38
+ * An MP4 or M4V with every user-data, metadata and uuid box in the movie, its
39
+ * tracks and the top level emptied in place: the box becomes a `free` box of
40
+ * the same size, zero-filled. That is where a phone writes the place a video
41
+ * was shot (`©xyz`, the QuickTime location key) and where XMP goes, and none
42
+ * of it is needed to play the file. Nothing moves, so every chunk offset in
43
+ * the sample tables still points at the same media data, whichever end of the
44
+ * file the movie box is at.
45
+ */
46
+ export function stripMovie(bytes) {
47
+ const out = Uint8Array.from(bytes);
48
+ const removed = [];
49
+ const walk = (start, end) => {
50
+ for (const box of boxes(bytes, start, end)) {
51
+ const label = MOVIE_LABELS[box.type];
52
+ if (label !== undefined) {
53
+ out.set(ascii('free'), box.start + 4);
54
+ out.fill(0, box.body, box.end);
55
+ removed.push(label);
56
+ }
57
+ else if (MOVIE_CONTAINERS.has(box.type)) {
58
+ walk(box.body, box.end);
59
+ }
60
+ }
61
+ };
62
+ walk(0, bytes.length);
63
+ return removed.length === 0 ? { bytes, removed } : { bytes: out, removed: unique(removed) };
64
+ }
65
+ /** An EXIF payload with nothing in it: a zero TIFF-header offset and a TIFF with an empty IFD. */
66
+ const EMPTY_EXIF = Uint8Array.from([
67
+ 0, 0, 0, 0, 0x4d, 0x4d, 0x00, 0x2a, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0,
68
+ ]);
69
+ /** An XMP packet with nothing in it; padding goes between the two halves, as XMP allows. */
70
+ const EMPTY_XMP_HEAD = ascii('<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?><x:xmpmeta xmlns:x="adobe:ns:meta/"/>');
71
+ const EMPTY_XMP_TAIL = ascii('<?xpacket end="w"?>');
72
+ function blankPayload(kind, length) {
73
+ const out = new Uint8Array(length);
74
+ if (kind === 'EXIF') {
75
+ if (length >= EMPTY_EXIF.length)
76
+ out.set(EMPTY_EXIF);
77
+ return out;
78
+ }
79
+ out.fill(0x20);
80
+ if (length >= EMPTY_XMP_HEAD.length + EMPTY_XMP_TAIL.length) {
81
+ out.set(EMPTY_XMP_HEAD);
82
+ out.set(EMPTY_XMP_TAIL, length - EMPTY_XMP_TAIL.length);
83
+ }
84
+ return out;
85
+ }
86
+ /**
87
+ * An AVIF whose Exif and XMP items are overwritten in place with an empty
88
+ * EXIF block and an empty, padded XMP packet of the same length.
89
+ *
90
+ * The items stay listed, so no box changes size and no item location needs
91
+ * rewriting; what they hold is gone. The picture's own orientation lives in
92
+ * its `irot` and `imir` properties, which are not metadata items and are left
93
+ * alone. The pixels are not touched, so nothing is re-encoded.
94
+ */
95
+ export function stripAvif(bytes) {
96
+ function fail(problem) {
97
+ throw new UnreadableMetadataError('AVIF', problem);
98
+ }
99
+ const meta = boxes(bytes, 0, bytes.length).find((box) => box.type === 'meta');
100
+ if (meta === undefined)
101
+ return { bytes, removed: [] };
102
+ // `meta` is a full box: a version and flags before its children.
103
+ const children = boxes(bytes, meta.body + 4, meta.end);
104
+ const iinf = children.find((box) => box.type === 'iinf');
105
+ const iloc = children.find((box) => box.type === 'iloc');
106
+ const idat = children.find((box) => box.type === 'idat');
107
+ if (iinf === undefined || iloc === undefined)
108
+ return { bytes, removed: [] };
109
+ const data = view(bytes);
110
+ const read = (at, size, limit) => {
111
+ if (at + size > limit)
112
+ fail('an item table runs past its box');
113
+ if (size === 0)
114
+ return 0;
115
+ if (size === 2)
116
+ return data.getUint16(at);
117
+ if (size === 4)
118
+ return data.getUint32(at);
119
+ if (size === 8)
120
+ return Number(data.getBigUint64(at));
121
+ return fail(`a field of ${String(size)} bytes`);
122
+ };
123
+ const metadataItems = new Map();
124
+ const iinfVersion = bytes[iinf.body] ?? 0;
125
+ const entriesAt = iinf.body + 4 + (iinfVersion === 0 ? 2 : 4);
126
+ for (const infe of boxes(bytes, entriesAt, iinf.end)) {
127
+ if (infe.type !== 'infe')
128
+ continue;
129
+ const version = bytes[infe.body] ?? 0;
130
+ if (version < 2)
131
+ continue;
132
+ const idSize = version === 2 ? 2 : 4;
133
+ const id = read(infe.body + 4, idSize, infe.end);
134
+ const typeAt = infe.body + 4 + idSize + 2;
135
+ if (typeAt + 4 > infe.end)
136
+ fail('an item entry is cut short');
137
+ const itemType = fourcc(bytes, typeAt);
138
+ if (itemType === 'Exif') {
139
+ metadataItems.set(id, 'EXIF');
140
+ }
141
+ else if (itemType === 'mime') {
142
+ const strings = Buffer.from(bytes.subarray(typeAt + 4, infe.end)).toString('latin1');
143
+ const contentType = strings.split('\0')[1] ?? '';
144
+ if (contentType.trim().toLowerCase() === 'application/rdf+xml')
145
+ metadataItems.set(id, 'XMP');
146
+ }
147
+ }
148
+ if (metadataItems.size === 0)
149
+ return { bytes, removed: [] };
150
+ const out = Uint8Array.from(bytes);
151
+ const removed = [];
152
+ const version = bytes[iloc.body] ?? 0;
153
+ let at = iloc.body + 4;
154
+ const sizes = read(at, 2, iloc.end);
155
+ const offsetSize = sizes >> 12;
156
+ const lengthSize = (sizes >> 8) & 0xf;
157
+ const baseOffsetSize = (sizes >> 4) & 0xf;
158
+ const indexSize = version === 0 ? 0 : sizes & 0xf;
159
+ at += 2;
160
+ const itemCount = read(at, version < 2 ? 2 : 4, iloc.end);
161
+ at += version < 2 ? 2 : 4;
162
+ for (let item = 0; item < itemCount; item += 1) {
163
+ const id = read(at, version < 2 ? 2 : 4, iloc.end);
164
+ at += version < 2 ? 2 : 4;
165
+ let method = 0;
166
+ if (version > 0) {
167
+ method = read(at, 2, iloc.end) & 0xf;
168
+ at += 2;
169
+ }
170
+ at += 2; // data_reference_index
171
+ const base = read(at, baseOffsetSize, iloc.end);
172
+ at += baseOffsetSize;
173
+ const extentCount = read(at, 2, iloc.end);
174
+ at += 2;
175
+ const extents = [];
176
+ for (let extent = 0; extent < extentCount; extent += 1) {
177
+ at += indexSize;
178
+ const offset = read(at, offsetSize, iloc.end);
179
+ at += offsetSize;
180
+ const length = read(at, lengthSize, iloc.end);
181
+ at += lengthSize;
182
+ extents.push([offset, length]);
183
+ }
184
+ const kind = metadataItems.get(id);
185
+ if (kind === undefined)
186
+ continue;
187
+ if (method > 1)
188
+ fail('an item is built from other items');
189
+ const area = method === 1 ? idat : { body: 0, end: bytes.length };
190
+ if (area === undefined)
191
+ fail('an item points into an idat that is not there');
192
+ const ranges = extents.map(([offset, length]) => {
193
+ const start = area.body + base + offset;
194
+ const end = length === 0 ? area.end : start + length;
195
+ if (end > area.end)
196
+ fail('an item runs past the end');
197
+ return [start, end];
198
+ });
199
+ const total = ranges.reduce((sum, [start, end]) => sum + end - start, 0);
200
+ const blank = blankPayload(kind, total);
201
+ let written = 0;
202
+ let changed = false;
203
+ for (const [start, end] of ranges) {
204
+ const part = blank.subarray(written, written + end - start);
205
+ if (!sameBytes(part, bytes.subarray(start, end)))
206
+ changed = true;
207
+ out.set(part, start);
208
+ written += end - start;
209
+ }
210
+ if (changed)
211
+ removed.push(kind);
212
+ }
213
+ return removed.length === 0 ? { bytes, removed } : { bytes: out, removed: unique(removed) };
214
+ }
215
+ //# sourceMappingURL=isobmff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isobmff.js","sourceRoot":"","sources":["../../../src/content/metadata/isobmff.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Stripped } from './shared.ts';
2
+ export declare function stripJpeg(bytes: Uint8Array): Stripped;
3
+ //# sourceMappingURL=jpeg.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jpeg.d.ts","sourceRoot":"","sources":["../../../src/content/metadata/jpeg.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAoC5C,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,QAAQ,CAkErD"}
@@ -0,0 +1,117 @@
1
+ import { ascii, concat, sameBytes, startsWith, stripped, UnreadableMetadataError, view, } from './shared.js';
2
+ import { keptExif } from './tiff.js';
3
+ const EXIF = ascii('Exif\0\0');
4
+ const ICC = ascii('ICC_PROFILE\0');
5
+ const ADOBE = ascii('Adobe');
6
+ const APP0 = 0xe0;
7
+ const APP1 = 0xe1;
8
+ const APP2 = 0xe2;
9
+ const APP13 = 0xed;
10
+ const APP14 = 0xee;
11
+ const APP15 = 0xef;
12
+ const COM = 0xfe;
13
+ const SOS = 0xda;
14
+ const EOI = 0xd9;
15
+ /**
16
+ * What one application segment is, by its marker and the name it opens with:
17
+ * a label to report when it goes, or `undefined` for one the picture needs.
18
+ *
19
+ * Kept: JFIF, the ICC colour profile and Adobe's colour-transform flag, each of
20
+ * which changes how the pixels decode. Everything else an APPn can hold is
21
+ * about the photo rather than the picture — EXIF, XMP, IPTC, the multi-picture
22
+ * index of a phone's depth map — and goes.
23
+ */
24
+ function segmentLabel(marker, body) {
25
+ if (marker === APP0)
26
+ return undefined;
27
+ if (marker === APP2 && startsWith(body, ICC))
28
+ return undefined;
29
+ if (marker === APP14 && startsWith(body, ADOBE))
30
+ return undefined;
31
+ if (marker === APP1)
32
+ return startsWith(body, EXIF) ? 'EXIF' : 'XMP';
33
+ if (marker === APP13)
34
+ return 'IPTC';
35
+ if (marker === COM)
36
+ return 'comment';
37
+ return `APP${String(marker - APP0)}`;
38
+ }
39
+ export function stripJpeg(bytes) {
40
+ function fail(problem) {
41
+ throw new UnreadableMetadataError('JPEG', problem);
42
+ }
43
+ const data = view(bytes);
44
+ const parts = [bytes.subarray(0, 2)];
45
+ const removed = [];
46
+ let at = 2;
47
+ while (at < bytes.length) {
48
+ if (bytes[at] !== 0xff)
49
+ fail(`expected a marker at byte ${String(at)}`);
50
+ // Any number of 0xFF may pad the space before a marker.
51
+ let markerAt = at;
52
+ while (bytes[markerAt + 1] === 0xff)
53
+ markerAt += 1;
54
+ const marker = bytes[markerAt + 1];
55
+ if (marker === undefined)
56
+ break;
57
+ if (marker === EOI) {
58
+ parts.push(bytes.subarray(markerAt, markerAt + 2));
59
+ if (markerAt + 2 < bytes.length)
60
+ removed.push('data after the image');
61
+ return stripped(bytes, parts, removed);
62
+ }
63
+ if ((marker >= 0xd0 && marker <= 0xd7) || marker === 0x01) {
64
+ parts.push(bytes.subarray(at, markerAt + 2));
65
+ at = markerAt + 2;
66
+ continue;
67
+ }
68
+ if (markerAt + 4 > bytes.length)
69
+ fail('a segment is cut off');
70
+ const end = markerAt + 2 + data.getUint16(markerAt + 2);
71
+ if (end > bytes.length || end < markerAt + 4)
72
+ fail('a segment runs past the end');
73
+ if ((marker >= APP0 && marker <= APP15) || marker === COM) {
74
+ const body = bytes.subarray(markerAt + 4, end);
75
+ const label = segmentLabel(marker, body);
76
+ if (label === undefined) {
77
+ parts.push(bytes.subarray(at, end));
78
+ }
79
+ else if (label === 'EXIF') {
80
+ const tiff = keptExif(body.subarray(EXIF.length));
81
+ const kept = tiff === undefined ? undefined : app1(tiff);
82
+ if (kept !== undefined)
83
+ parts.push(kept);
84
+ if (kept === undefined || !sameBytes(kept, bytes.subarray(at, end)))
85
+ removed.push('EXIF');
86
+ }
87
+ else {
88
+ removed.push(label);
89
+ }
90
+ at = end;
91
+ continue;
92
+ }
93
+ parts.push(bytes.subarray(at, end));
94
+ at = end;
95
+ if (marker === SOS) {
96
+ // Entropy-coded data runs to the next marker: an 0xFF that is neither a
97
+ // stuffed zero nor a restart marker.
98
+ let scan = at;
99
+ while (scan + 1 < bytes.length) {
100
+ const next = bytes[scan + 1];
101
+ if (bytes[scan] === 0xff && next !== 0x00 && !(next >= 0xd0 && next <= 0xd7))
102
+ break;
103
+ scan += 1;
104
+ }
105
+ if (scan + 1 >= bytes.length)
106
+ scan = bytes.length;
107
+ parts.push(bytes.subarray(at, scan));
108
+ at = scan;
109
+ }
110
+ }
111
+ return stripped(bytes, parts, removed);
112
+ }
113
+ function app1(tiff) {
114
+ const length = 2 + EXIF.length + tiff.length;
115
+ return concat([Uint8Array.from([0xff, APP1, length >> 8, length & 0xff]), EXIF, tiff]);
116
+ }
117
+ //# sourceMappingURL=jpeg.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jpeg.js","sourceRoot":"","sources":["../../../src/content/metadata/jpeg.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Stripped } from './shared.ts';
2
+ export declare function stripPng(bytes: Uint8Array): Stripped;
3
+ //# sourceMappingURL=png.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"png.d.ts","sourceRoot":"","sources":["../../../src/content/metadata/png.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AA+B5C,wBAAgB,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,QAAQ,CAiCpD"}
@@ -0,0 +1,74 @@
1
+ import { crc32 } from 'node:zlib';
2
+ import { ascii, concat, fourcc, sameBytes, stripped, view } from './shared.js';
3
+ import { keptExif } from './tiff.js';
4
+ /** Critical chunks are kept too, outside this set: a decoder must refuse a file missing one. */
5
+ const RENDERING = new Set([
6
+ 'tRNS',
7
+ 'cHRM',
8
+ 'gAMA',
9
+ 'iCCP',
10
+ 'sBIT',
11
+ 'sRGB',
12
+ 'cICP',
13
+ 'mDCV',
14
+ 'cLLI',
15
+ 'bKGD',
16
+ 'hIST',
17
+ 'pHYs',
18
+ 'sPLT',
19
+ 'acTL',
20
+ 'fcTL',
21
+ 'fdAT',
22
+ ]);
23
+ const LABELS = {
24
+ eXIf: 'EXIF',
25
+ tEXt: 'text',
26
+ zTXt: 'text',
27
+ iTXt: 'text',
28
+ tIME: 'timestamp',
29
+ };
30
+ export function stripPng(bytes) {
31
+ const data = view(bytes);
32
+ const parts = [bytes.subarray(0, 8)];
33
+ const removed = [];
34
+ for (let at = 8; at < bytes.length;) {
35
+ if (at + 8 > bytes.length) {
36
+ parts.push(bytes.subarray(at));
37
+ break;
38
+ }
39
+ const type = fourcc(bytes, at + 4);
40
+ const end = Math.min(bytes.length, at + 12 + data.getUint32(at));
41
+ const critical = (bytes[at + 4] & 0x20) === 0;
42
+ if (type === 'eXIf') {
43
+ const tiff = keptExif(bytes.subarray(at + 8, end - 4));
44
+ const kept = tiff === undefined ? undefined : chunk('eXIf', tiff);
45
+ if (kept !== undefined)
46
+ parts.push(kept);
47
+ if (kept === undefined || !sameBytes(kept, bytes.subarray(at, end)))
48
+ removed.push('EXIF');
49
+ }
50
+ else if (critical || RENDERING.has(type)) {
51
+ parts.push(bytes.subarray(at, end));
52
+ }
53
+ else {
54
+ removed.push(LABELS[type] ?? `${type} chunk`);
55
+ }
56
+ at = end;
57
+ if (type === 'IEND') {
58
+ if (at < bytes.length)
59
+ removed.push('data after the image');
60
+ break;
61
+ }
62
+ }
63
+ return stripped(bytes, parts, removed);
64
+ }
65
+ function chunk(type, body) {
66
+ const typed = concat([ascii(type), body]);
67
+ const out = new Uint8Array(body.length + 12);
68
+ const data = view(out);
69
+ data.setUint32(0, body.length);
70
+ out.set(typed, 4);
71
+ data.setUint32(8 + body.length, crc32(typed));
72
+ return out;
73
+ }
74
+ //# sourceMappingURL=png.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"png.js","sourceRoot":"","sources":["../../../src/content/metadata/png.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ export interface Stripped {
2
+ bytes: Uint8Array;
3
+ removed: readonly string[];
4
+ }
5
+ export type Stripper = (bytes: Uint8Array) => Stripped;
6
+ export declare class UnreadableMetadataError extends Error {
7
+ constructor(format: string, problem: string);
8
+ }
9
+ export declare function ascii(value: string): Uint8Array;
10
+ export declare function fourcc(bytes: Uint8Array, at: number): string;
11
+ export declare function startsWith(bytes: Uint8Array, prefix: Uint8Array, at?: number): boolean;
12
+ export declare function sameBytes(a: Uint8Array, b: Uint8Array): boolean;
13
+ export declare function concat(parts: readonly Uint8Array[]): Uint8Array;
14
+ export declare function view(bytes: Uint8Array): DataView;
15
+ export declare function unique(labels: readonly string[]): string[];
16
+ export declare function stripped(original: Uint8Array, parts: readonly Uint8Array[], removed: readonly string[]): Stripped;
17
+ //# sourceMappingURL=shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/content/metadata/shared.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,UAAU,CAAC;IAClB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,MAAM,QAAQ,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,QAAQ,CAAC;AAEvD,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,YAAY,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAG1C;CACF;AAED,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAE/C;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,SAAI,GAAG,OAAO,CAGjF;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,OAAO,CAE/D;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,UAAU,CAQ/D;AAED,wBAAgB,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,QAAQ,CAEhD;AAED,wBAAgB,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAE1D;AAED,wBAAgB,QAAQ,CACtB,QAAQ,EAAE,UAAU,EACpB,KAAK,EAAE,SAAS,UAAU,EAAE,EAC5B,OAAO,EAAE,SAAS,MAAM,EAAE,GACzB,QAAQ,CAIV"}
@@ -0,0 +1,42 @@
1
+ export class UnreadableMetadataError extends Error {
2
+ constructor(format, problem) {
3
+ super(`This ${format} could not be read: ${problem}.`);
4
+ this.name = 'UnreadableMetadataError';
5
+ }
6
+ }
7
+ export function ascii(value) {
8
+ return Uint8Array.from(value, (character) => character.charCodeAt(0));
9
+ }
10
+ export function fourcc(bytes, at) {
11
+ return String.fromCharCode(...bytes.subarray(at, at + 4));
12
+ }
13
+ export function startsWith(bytes, prefix, at = 0) {
14
+ if (at + prefix.length > bytes.length)
15
+ return false;
16
+ return prefix.every((byte, index) => bytes[at + index] === byte);
17
+ }
18
+ export function sameBytes(a, b) {
19
+ return a.length === b.length && a.every((byte, index) => b[index] === byte);
20
+ }
21
+ export function concat(parts) {
22
+ const out = new Uint8Array(parts.reduce((total, part) => total + part.length, 0));
23
+ let at = 0;
24
+ for (const part of parts) {
25
+ out.set(part, at);
26
+ at += part.length;
27
+ }
28
+ return out;
29
+ }
30
+ export function view(bytes) {
31
+ return new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
32
+ }
33
+ export function unique(labels) {
34
+ return [...new Set(labels)];
35
+ }
36
+ export function stripped(original, parts, removed) {
37
+ const bytes = concat(parts);
38
+ if (sameBytes(bytes, original))
39
+ return { bytes: original, removed: [] };
40
+ return { bytes, removed: unique(removed) };
41
+ }
42
+ //# sourceMappingURL=shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/content/metadata/shared.ts"],"names":[],"mappings":"AAOA,MAAM,OAAO,uBAAwB,SAAQ,KAAK;IAChD,YAAY,MAAc,EAAE,OAAe;QACzC,KAAK,CAAC,QAAQ,MAAM,uBAAuB,OAAO,GAAG,CAAC,CAAC;QACvD,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;IACxC,CAAC;CACF;AAED,MAAM,UAAU,KAAK,CAAC,KAAa;IACjC,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,KAAiB,EAAE,EAAU;IAClD,OAAO,MAAM,CAAC,YAAY,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAiB,EAAE,MAAkB,EAAE,EAAE,GAAG,CAAC;IACtE,IAAI,EAAE,GAAG,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACpD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,CAAa,EAAE,CAAa;IACpD,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,KAA4B;IACjD,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;IAClF,IAAI,EAAE,GAAG,CAAC,CAAC;IACX,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAClB,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC;IACpB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,KAAiB;IACpC,OAAO,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,MAAyB;IAC9C,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,QAAQ,CACtB,QAAoB,EACpB,KAA4B,EAC5B,OAA0B;IAE1B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5B,IAAI,SAAS,CAAC,KAAK,EAAE,QAAQ,CAAC;QAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IACxE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,14 @@
1
+ export type SweptFile = {
2
+ path: string;
3
+ outcome: 'stripped';
4
+ removed: readonly string[];
5
+ } | {
6
+ path: string;
7
+ outcome: 'clean';
8
+ } | {
9
+ path: string;
10
+ outcome: 'unreadable';
11
+ problem: string;
12
+ };
13
+ export declare function stripStoredUploads(directory: string): Promise<SweptFile[]>;
14
+ //# sourceMappingURL=sweep.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sweep.d.ts","sourceRoot":"","sources":["../../../src/content/metadata/sweep.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,SAAS,GACjB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GACjE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7D,wBAAsB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CA4BhF"}
@@ -0,0 +1,54 @@
1
+ import { readdir, readFile, rename, stat, utimes, writeFile } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { stripMetadata, strippable, UnreadableMetadataError } from './index.js';
4
+ export async function stripStoredUploads(directory) {
5
+ const files = await listFiles(directory);
6
+ const results = [];
7
+ for (const relative of files) {
8
+ if (!strippable(path.extname(relative)))
9
+ continue;
10
+ const file = path.join(directory, ...relative.split('/'));
11
+ const bytes = new Uint8Array(await readFile(file));
12
+ let result;
13
+ try {
14
+ result = stripMetadata(path.extname(relative), bytes);
15
+ }
16
+ catch (error) {
17
+ if (!(error instanceof UnreadableMetadataError))
18
+ throw error;
19
+ results.push({ path: relative, outcome: 'unreadable', problem: error.message });
20
+ continue;
21
+ }
22
+ if (result.bytes === bytes) {
23
+ results.push({ path: relative, outcome: 'clean' });
24
+ continue;
25
+ }
26
+ await replaceKeepingTimes(file, result.bytes);
27
+ results.push({ path: relative, outcome: 'stripped', removed: result.removed });
28
+ }
29
+ return results;
30
+ }
31
+ async function listFiles(directory) {
32
+ let entries;
33
+ try {
34
+ entries = await readdir(directory, { recursive: true, withFileTypes: true });
35
+ }
36
+ catch (error) {
37
+ if (error.code === 'ENOENT')
38
+ return [];
39
+ throw error;
40
+ }
41
+ return entries
42
+ .filter((entry) => entry.isFile())
43
+ .map((entry) => path.relative(directory, path.join(entry.parentPath, entry.name)))
44
+ .map((relative) => relative.split(path.sep).join('/'))
45
+ .sort();
46
+ }
47
+ async function replaceKeepingTimes(file, bytes) {
48
+ const { atime, mtime } = await stat(file);
49
+ const temporary = `${file}.geekity-strip`;
50
+ await writeFile(temporary, bytes);
51
+ await utimes(temporary, atime, mtime);
52
+ await rename(temporary, file);
53
+ }
54
+ //# sourceMappingURL=sweep.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sweep.js","sourceRoot":"","sources":["../../../src/content/metadata/sweep.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * What a format should keep of an EXIF block: the orientation alone when the
3
+ * picture is turned, since dropping it would show a phone photo sideways, and
4
+ * nothing when it is upright.
5
+ */
6
+ export declare function keptExif(tiff: Uint8Array): Uint8Array | undefined;
7
+ //# sourceMappingURL=tiff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tiff.d.ts","sourceRoot":"","sources":["../../../src/content/metadata/tiff.ts"],"names":[],"mappings":"AAgDA;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,GAAG,SAAS,CAGjE"}