@openrails/contentkit-ui 0.0.0-stage → 0.68.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 (367) hide show
  1. package/README.md +425 -2
  2. package/dist/appearance.d.ts +38 -0
  3. package/dist/appearance.js +15 -0
  4. package/dist/appearance.js.map +1 -0
  5. package/dist/assets/hash.worker-BYfo-7MQ.js.map +1 -0
  6. package/dist/client/aspect.d.ts +6 -0
  7. package/dist/client/aspect.js +17 -0
  8. package/dist/client/aspect.js.map +1 -0
  9. package/dist/client/client.d.ts +51 -0
  10. package/dist/client/client.js +35 -0
  11. package/dist/client/client.js.map +1 -0
  12. package/dist/client/codes.d.ts +12 -0
  13. package/dist/client/codes.js +19 -0
  14. package/dist/client/codes.js.map +1 -0
  15. package/dist/client/content/bans.d.ts +15 -0
  16. package/dist/client/content/bans.js +40 -0
  17. package/dist/client/content/bans.js.map +1 -0
  18. package/dist/client/content/comments.d.ts +36 -0
  19. package/dist/client/content/comments.js +93 -0
  20. package/dist/client/content/comments.js.map +1 -0
  21. package/dist/client/content/favorites.d.ts +14 -0
  22. package/dist/client/content/favorites.js +42 -0
  23. package/dist/client/content/favorites.js.map +1 -0
  24. package/dist/client/content/moderation.d.ts +18 -0
  25. package/dist/client/content/moderation.js +37 -0
  26. package/dist/client/content/moderation.js.map +1 -0
  27. package/dist/client/content/polls.d.ts +47 -0
  28. package/dist/client/content/polls.js +148 -0
  29. package/dist/client/content/polls.js.map +1 -0
  30. package/dist/client/content/posts.d.ts +44 -0
  31. package/dist/client/content/posts.js +91 -0
  32. package/dist/client/content/posts.js.map +1 -0
  33. package/dist/client/content/reactions.d.ts +12 -0
  34. package/dist/client/content/reactions.js +36 -0
  35. package/dist/client/content/reactions.js.map +1 -0
  36. package/dist/client/content/types.d.ts +91 -0
  37. package/dist/client/content/types.js +8 -0
  38. package/dist/client/content/types.js.map +1 -0
  39. package/dist/client/crop.d.ts +32 -0
  40. package/dist/client/crop.js +103 -0
  41. package/dist/client/crop.js.map +1 -0
  42. package/dist/client/errors.d.ts +54 -0
  43. package/dist/client/errors.js +80 -0
  44. package/dist/client/errors.js.map +1 -0
  45. package/dist/client/gallery.d.ts +43 -0
  46. package/dist/client/gallery.js +86 -0
  47. package/dist/client/gallery.js.map +1 -0
  48. package/dist/client/generated/error-codes.d.ts +5 -0
  49. package/dist/client/generated/error-codes.js +131 -0
  50. package/dist/client/generated/error-codes.js.map +1 -0
  51. package/dist/client/generated/routes.d.ts +1086 -0
  52. package/dist/client/generated/routes.js +1400 -0
  53. package/dist/client/generated/routes.js.map +1 -0
  54. package/dist/client/generated/wire.d.ts +630 -0
  55. package/dist/client/generated/wire.js +6 -0
  56. package/dist/client/generated/wire.js.map +1 -0
  57. package/dist/client/http.d.ts +79 -0
  58. package/dist/client/http.js +74 -0
  59. package/dist/client/http.js.map +1 -0
  60. package/dist/client/image.d.ts +24 -0
  61. package/dist/client/image.js +65 -0
  62. package/dist/client/image.js.map +1 -0
  63. package/dist/client/index.d.ts +33 -0
  64. package/dist/client/media/api.d.ts +36 -0
  65. package/dist/client/media/api.js +61 -0
  66. package/dist/client/media/api.js.map +1 -0
  67. package/dist/client/media/client.d.ts +247 -0
  68. package/dist/client/media/client.js +407 -0
  69. package/dist/client/media/client.js.map +1 -0
  70. package/dist/client/media/encode.d.ts +3 -0
  71. package/dist/client/media/encode.js +8 -0
  72. package/dist/client/media/encode.js.map +1 -0
  73. package/dist/client/media/hash-stream.d.ts +6 -0
  74. package/dist/client/media/hash-stream.js +16 -0
  75. package/dist/client/media/hash-stream.js.map +1 -0
  76. package/dist/client/media/hash.d.ts +12 -0
  77. package/dist/client/media/hash.js +48 -0
  78. package/dist/client/media/hash.js.map +1 -0
  79. package/dist/client/media/hash.worker-inline.js +18 -0
  80. package/dist/client/media/hash.worker-inline.js.map +1 -0
  81. package/dist/client/media/pacer.d.ts +21 -0
  82. package/dist/client/media/pacer.js +25 -0
  83. package/dist/client/media/pacer.js.map +1 -0
  84. package/dist/client/media/queue.d.ts +112 -0
  85. package/dist/client/media/queue.js +274 -0
  86. package/dist/client/media/queue.js.map +1 -0
  87. package/dist/client/media/ref.d.ts +6 -0
  88. package/dist/client/media/ref.js +10 -0
  89. package/dist/client/media/ref.js.map +1 -0
  90. package/dist/client/media/rules.d.ts +52 -0
  91. package/dist/client/media/rules.js +139 -0
  92. package/dist/client/media/rules.js.map +1 -0
  93. package/dist/client/media/transport.d.ts +13 -0
  94. package/dist/client/media/transport.js +33 -0
  95. package/dist/client/media/transport.js.map +1 -0
  96. package/dist/client/media/windows.d.ts +15 -0
  97. package/dist/client/media/windows.js +39 -0
  98. package/dist/client/media/windows.js.map +1 -0
  99. package/dist/client/playback.d.ts +200 -0
  100. package/dist/client/playback.js +142 -0
  101. package/dist/client/playback.js.map +1 -0
  102. package/dist/client/player.d.ts +102 -0
  103. package/dist/client/player.js +155 -0
  104. package/dist/client/player.js.map +1 -0
  105. package/dist/client/public.d.ts +25 -0
  106. package/dist/client/public.js +18 -0
  107. package/dist/client/public.js.map +1 -0
  108. package/dist/client/rendition.d.ts +19 -0
  109. package/dist/client/rendition.js +16 -0
  110. package/dist/client/rendition.js.map +1 -0
  111. package/dist/client/route.d.ts +39 -0
  112. package/dist/client/route.js +31 -0
  113. package/dist/client/route.js.map +1 -0
  114. package/dist/client/taxonomy.d.ts +30 -0
  115. package/dist/client/taxonomy.js +77 -0
  116. package/dist/client/taxonomy.js.map +1 -0
  117. package/dist/client.js +33 -0
  118. package/dist/components/encode-progress.d.ts +15 -0
  119. package/dist/components/encode-progress.js +49 -0
  120. package/dist/components/encode-progress.js.map +1 -0
  121. package/dist/components/hover-preview.d.ts +29 -0
  122. package/dist/components/hover-preview.js +49 -0
  123. package/dist/components/hover-preview.js.map +1 -0
  124. package/dist/components/image-crop-dialog.d.ts +48 -0
  125. package/dist/components/image-crop-dialog.js +359 -0
  126. package/dist/components/image-crop-dialog.js.map +1 -0
  127. package/dist/components/lazy-mount.d.ts +10 -0
  128. package/dist/components/lazy-mount.js +22 -0
  129. package/dist/components/lazy-mount.js.map +1 -0
  130. package/dist/components/media-folder-editor.d.ts +45 -0
  131. package/dist/components/media-folder-editor.js +564 -0
  132. package/dist/components/media-folder-editor.js.map +1 -0
  133. package/dist/components/media-gallery.d.ts +54 -0
  134. package/dist/components/media-gallery.js +597 -0
  135. package/dist/components/media-gallery.js.map +1 -0
  136. package/dist/components/media-readiness-notice.d.ts +24 -0
  137. package/dist/components/media-readiness-notice.js +61 -0
  138. package/dist/components/media-readiness-notice.js.map +1 -0
  139. package/dist/components/player-controls.d.ts +71 -0
  140. package/dist/components/player-controls.js +264 -0
  141. package/dist/components/player-controls.js.map +1 -0
  142. package/dist/components/progress.d.ts +5 -0
  143. package/dist/components/progress.js +14 -0
  144. package/dist/components/progress.js.map +1 -0
  145. package/dist/components/rendition-img.d.ts +34 -0
  146. package/dist/components/rendition-img.js +78 -0
  147. package/dist/components/rendition-img.js.map +1 -0
  148. package/dist/components/slot-editor.d.ts +95 -0
  149. package/dist/components/slot-editor.js +182 -0
  150. package/dist/components/slot-editor.js.map +1 -0
  151. package/dist/components/slot-image.d.ts +23 -0
  152. package/dist/components/slot-image.js +48 -0
  153. package/dist/components/slot-image.js.map +1 -0
  154. package/dist/components/slot-upload.d.ts +41 -0
  155. package/dist/components/slot-upload.js +213 -0
  156. package/dist/components/slot-upload.js.map +1 -0
  157. package/dist/components/social/bans.d.ts +42 -0
  158. package/dist/components/social/bans.js +300 -0
  159. package/dist/components/social/bans.js.map +1 -0
  160. package/dist/components/social/comments.d.ts +42 -0
  161. package/dist/components/social/comments.js +517 -0
  162. package/dist/components/social/comments.js.map +1 -0
  163. package/dist/components/social/engagement.d.ts +45 -0
  164. package/dist/components/social/engagement.js +129 -0
  165. package/dist/components/social/engagement.js.map +1 -0
  166. package/dist/components/social/index.d.ts +6 -0
  167. package/dist/components/social/moderation.d.ts +32 -0
  168. package/dist/components/social/moderation.js +383 -0
  169. package/dist/components/social/moderation.js.map +1 -0
  170. package/dist/components/social/parts.d.ts +50 -0
  171. package/dist/components/social/parts.js +106 -0
  172. package/dist/components/social/parts.js.map +1 -0
  173. package/dist/components/social/poll-editor.d.ts +34 -0
  174. package/dist/components/social/poll-editor.js +567 -0
  175. package/dist/components/social/poll-editor.js.map +1 -0
  176. package/dist/components/social/poll.d.ts +30 -0
  177. package/dist/components/social/poll.js +252 -0
  178. package/dist/components/social/poll.js.map +1 -0
  179. package/dist/components/sortable-list.d.ts +29 -0
  180. package/dist/components/sortable-list.js +121 -0
  181. package/dist/components/sortable-list.js.map +1 -0
  182. package/dist/components/video-mini-player.d.ts +35 -0
  183. package/dist/components/video-mini-player.js +236 -0
  184. package/dist/components/video-mini-player.js.map +1 -0
  185. package/dist/components/video-player.d.ts +146 -0
  186. package/dist/components/video-player.js +630 -0
  187. package/dist/components/video-player.js.map +1 -0
  188. package/dist/components/video-poster-picker.d.ts +59 -0
  189. package/dist/components/video-poster-picker.js +335 -0
  190. package/dist/components/video-poster-picker.js.map +1 -0
  191. package/dist/components/video-poster.d.ts +24 -0
  192. package/dist/components/video-poster.js +46 -0
  193. package/dist/components/video-poster.js.map +1 -0
  194. package/dist/i18n/context.d.ts +4 -0
  195. package/dist/i18n/context.js +11 -0
  196. package/dist/i18n/context.js.map +1 -0
  197. package/dist/i18n/messages.d.ts +40 -0
  198. package/dist/i18n/messages.js +94 -0
  199. package/dist/i18n/messages.js.map +1 -0
  200. package/dist/index.d.ts +23 -0
  201. package/dist/index.js +41 -0
  202. package/dist/locales/de.d.ts +2 -0
  203. package/dist/locales/de.js +271 -0
  204. package/dist/locales/de.js.map +1 -0
  205. package/dist/locales/en.d.ts +457 -0
  206. package/dist/locales/en.js +271 -0
  207. package/dist/locales/en.js.map +1 -0
  208. package/dist/locales/es.d.ts +2 -0
  209. package/dist/locales/es.js +271 -0
  210. package/dist/locales/es.js.map +1 -0
  211. package/dist/locales/ja.d.ts +2 -0
  212. package/dist/locales/ja.js +271 -0
  213. package/dist/locales/ja.js.map +1 -0
  214. package/dist/locales/ko.d.ts +2 -0
  215. package/dist/locales/ko.js +271 -0
  216. package/dist/locales/ko.js.map +1 -0
  217. package/dist/locales/social/de.d.ts +2 -0
  218. package/dist/locales/social/de.js +198 -0
  219. package/dist/locales/social/de.js.map +1 -0
  220. package/dist/locales/social/en.d.ts +195 -0
  221. package/dist/locales/social/en.js +198 -0
  222. package/dist/locales/social/en.js.map +1 -0
  223. package/dist/locales/social/es.d.ts +2 -0
  224. package/dist/locales/social/es.js +198 -0
  225. package/dist/locales/social/es.js.map +1 -0
  226. package/dist/locales/social/ja.d.ts +2 -0
  227. package/dist/locales/social/ja.js +198 -0
  228. package/dist/locales/social/ja.js.map +1 -0
  229. package/dist/locales/social/ko.d.ts +2 -0
  230. package/dist/locales/social/ko.js +198 -0
  231. package/dist/locales/social/ko.js.map +1 -0
  232. package/dist/locales/social/zh.d.ts +2 -0
  233. package/dist/locales/social/zh.js +198 -0
  234. package/dist/locales/social/zh.js.map +1 -0
  235. package/dist/locales/zh.d.ts +2 -0
  236. package/dist/locales/zh.js +271 -0
  237. package/dist/locales/zh.js.map +1 -0
  238. package/dist/provider.d.ts +22 -0
  239. package/dist/provider.js +59 -0
  240. package/dist/provider.js.map +1 -0
  241. package/dist/react/canonical.d.ts +33 -0
  242. package/dist/react/canonical.js +88 -0
  243. package/dist/react/canonical.js.map +1 -0
  244. package/dist/react/comments.d.ts +82 -0
  245. package/dist/react/comments.js +147 -0
  246. package/dist/react/comments.js.map +1 -0
  247. package/dist/react/config.d.ts +13 -0
  248. package/dist/react/config.js +14 -0
  249. package/dist/react/config.js.map +1 -0
  250. package/dist/react/context.d.ts +48 -0
  251. package/dist/react/context.js +37 -0
  252. package/dist/react/context.js.map +1 -0
  253. package/dist/react/crop.d.ts +49 -0
  254. package/dist/react/crop.js +107 -0
  255. package/dist/react/crop.js.map +1 -0
  256. package/dist/react/engagement.d.ts +38 -0
  257. package/dist/react/engagement.js +88 -0
  258. package/dist/react/engagement.js.map +1 -0
  259. package/dist/react/folder.d.ts +83 -0
  260. package/dist/react/folder.js +183 -0
  261. package/dist/react/folder.js.map +1 -0
  262. package/dist/react/gallery.d.ts +140 -0
  263. package/dist/react/gallery.js +477 -0
  264. package/dist/react/gallery.js.map +1 -0
  265. package/dist/react/index.d.ts +21 -0
  266. package/dist/react/inline-preview.d.ts +24 -0
  267. package/dist/react/inline-preview.js +76 -0
  268. package/dist/react/inline-preview.js.map +1 -0
  269. package/dist/react/player.d.ts +70 -0
  270. package/dist/react/player.js +214 -0
  271. package/dist/react/player.js.map +1 -0
  272. package/dist/react/polls.d.ts +74 -0
  273. package/dist/react/polls.js +176 -0
  274. package/dist/react/polls.js.map +1 -0
  275. package/dist/react/posts.d.ts +59 -0
  276. package/dist/react/posts.js +149 -0
  277. package/dist/react/posts.js.map +1 -0
  278. package/dist/react/provider.d.ts +23 -0
  279. package/dist/react/provider.js +35 -0
  280. package/dist/react/provider.js.map +1 -0
  281. package/dist/react/public.d.ts +39 -0
  282. package/dist/react/public.js +70 -0
  283. package/dist/react/public.js.map +1 -0
  284. package/dist/react/read.d.ts +52 -0
  285. package/dist/react/read.js +143 -0
  286. package/dist/react/read.js.map +1 -0
  287. package/dist/react/resources.d.ts +70 -0
  288. package/dist/react/resources.js +247 -0
  289. package/dist/react/resources.js.map +1 -0
  290. package/dist/react/slot.d.ts +102 -0
  291. package/dist/react/slot.js +181 -0
  292. package/dist/react/slot.js.map +1 -0
  293. package/dist/react/store.d.ts +51 -0
  294. package/dist/react/store.js +164 -0
  295. package/dist/react/store.js.map +1 -0
  296. package/dist/react/upload.d.ts +85 -0
  297. package/dist/react/upload.js +150 -0
  298. package/dist/react/upload.js.map +1 -0
  299. package/dist/react/use-resource.d.ts +43 -0
  300. package/dist/react/use-resource.js +66 -0
  301. package/dist/react/use-resource.js.map +1 -0
  302. package/dist/react/video.d.ts +118 -0
  303. package/dist/react/video.js +184 -0
  304. package/dist/react/video.js.map +1 -0
  305. package/dist/react/viewport.d.ts +19 -0
  306. package/dist/react/viewport.js +30 -0
  307. package/dist/react/viewport.js.map +1 -0
  308. package/dist/react.js +21 -0
  309. package/dist/scope.d.ts +14 -0
  310. package/dist/scope.js +30 -0
  311. package/dist/scope.js.map +1 -0
  312. package/dist/styles.css +3 -0
  313. package/dist/ui/alert-dialog.d.ts +18 -0
  314. package/dist/ui/alert-dialog.js +86 -0
  315. package/dist/ui/alert-dialog.js.map +1 -0
  316. package/dist/ui/alert.d.ts +10 -0
  317. package/dist/ui/alert.js +38 -0
  318. package/dist/ui/alert.js.map +1 -0
  319. package/dist/ui/avatar.d.ts +11 -0
  320. package/dist/ui/avatar.js +31 -0
  321. package/dist/ui/avatar.js.map +1 -0
  322. package/dist/ui/badge.d.ts +7 -0
  323. package/dist/ui/badge.js +31 -0
  324. package/dist/ui/badge.js.map +1 -0
  325. package/dist/ui/button.d.ts +8 -0
  326. package/dist/ui/button.js +46 -0
  327. package/dist/ui/button.js.map +1 -0
  328. package/dist/ui/dialog.d.ts +17 -0
  329. package/dist/ui/dialog.js +91 -0
  330. package/dist/ui/dialog.js.map +1 -0
  331. package/dist/ui/dropdown-menu.d.ts +15 -0
  332. package/dist/ui/dropdown-menu.js +105 -0
  333. package/dist/ui/dropdown-menu.js.map +1 -0
  334. package/dist/ui/input.d.ts +3 -0
  335. package/dist/ui/input.js +17 -0
  336. package/dist/ui/input.js.map +1 -0
  337. package/dist/ui/label.d.ts +3 -0
  338. package/dist/ui/label.js +15 -0
  339. package/dist/ui/label.js.map +1 -0
  340. package/dist/ui/progress.d.ts +7 -0
  341. package/dist/ui/progress.js +31 -0
  342. package/dist/ui/progress.js.map +1 -0
  343. package/dist/ui/select.d.ts +15 -0
  344. package/dist/ui/select.js +98 -0
  345. package/dist/ui/select.js.map +1 -0
  346. package/dist/ui/skeleton.d.ts +2 -0
  347. package/dist/ui/skeleton.js +14 -0
  348. package/dist/ui/skeleton.js.map +1 -0
  349. package/dist/ui/slider.d.ts +3 -0
  350. package/dist/ui/slider.js +35 -0
  351. package/dist/ui/slider.js.map +1 -0
  352. package/dist/ui/switch.d.ts +5 -0
  353. package/dist/ui/switch.js +20 -0
  354. package/dist/ui/switch.js.map +1 -0
  355. package/dist/ui/tabs.d.ts +10 -0
  356. package/dist/ui/tabs.js +47 -0
  357. package/dist/ui/tabs.js.map +1 -0
  358. package/dist/ui/textarea.d.ts +3 -0
  359. package/dist/ui/textarea.js +15 -0
  360. package/dist/ui/textarea.js.map +1 -0
  361. package/dist/ui/toggle-group.d.ts +5 -0
  362. package/dist/ui/toggle-group.js +23 -0
  363. package/dist/ui/toggle-group.js.map +1 -0
  364. package/dist/urls/index.d.ts +100 -0
  365. package/dist/urls.js +118 -0
  366. package/dist/urls.js.map +1 -0
  367. package/package.json +118 -3
@@ -0,0 +1,18 @@
1
+ import { HeldItem, HeldPage, ReviewOutcome } from '../generated/wire.js';
2
+ import { Http } from '../http.js';
3
+ import { Decision, HeldKind } from './types.js';
4
+ export interface HeldQuery {
5
+ kind: HeldKind;
6
+ /** The previous page's next. */
7
+ cursor?: string;
8
+ limit?: number;
9
+ }
10
+ /** The review queue of held comments and posts (ModerationReview). */
11
+ export declare class ModerationClient {
12
+ private readonly http;
13
+ constructor(http: Http);
14
+ /** Held items awaiting review, oldest first. */
15
+ held(q: HeldQuery, signal?: AbortSignal): Promise<HeldPage>;
16
+ /** Approves (publishes) or rejects a held item at the revision the queue listed; conflict when it was edited since. */
17
+ resolve(item: Pick<HeldItem, "kind" | "id" | "revision">, decision: Decision, reason?: string): Promise<ReviewOutcome>;
18
+ }
@@ -0,0 +1,37 @@
1
+ import { call as e } from "../route.js";
2
+ //#region src/client/content/moderation.ts
3
+ var t = class {
4
+ http;
5
+ constructor(e) {
6
+ this.http = e;
7
+ }
8
+ held(t, n) {
9
+ return e(this.http, "GET", "/moderation/held", {
10
+ query: { ...t },
11
+ signal: n
12
+ });
13
+ }
14
+ async resolve(t, n, r) {
15
+ let i = t.kind, a = await e(this.http, "POST", "/moderation/{kind}/{id}/resolve", {
16
+ params: {
17
+ kind: i,
18
+ id: t.id
19
+ },
20
+ body: {
21
+ decision: n,
22
+ revision: t.revision,
23
+ ...r ? { reason: r } : {}
24
+ }
25
+ });
26
+ return this.http.emit({
27
+ type: "moderation.resolved",
28
+ kind: i,
29
+ id: t.id,
30
+ decision: n
31
+ }), a;
32
+ }
33
+ };
34
+ //#endregion
35
+ export { t as ModerationClient };
36
+
37
+ //# sourceMappingURL=moderation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"moderation.js","names":[],"sources":["../../../src/client/content/moderation.ts"],"sourcesContent":["import type { HeldItem, HeldPage, ReviewOutcome } from \"../generated/wire.js\";\nimport type { Http } from \"../http.js\";\nimport { call } from \"../route.js\";\nimport type { Decision, HeldKind } from \"./types.js\";\n\nexport interface HeldQuery {\n kind: HeldKind;\n /** The previous page's next. */\n cursor?: string;\n limit?: number;\n}\n\n/** The review queue of held comments and posts (ModerationReview). */\nexport class ModerationClient {\n constructor(private readonly http: Http) {}\n\n /** Held items awaiting review, oldest first. */\n held(q: HeldQuery, signal?: AbortSignal): Promise<HeldPage> {\n return call(this.http, \"GET\", \"/moderation/held\", { query: { ...q }, signal });\n }\n /** Approves (publishes) or rejects a held item at the revision the queue listed; conflict when it was edited since. */\n async resolve(item: Pick<HeldItem, \"kind\" | \"id\" | \"revision\">, decision: Decision, reason?: string): Promise<ReviewOutcome> {\n const kind = item.kind as HeldKind;\n const out: ReviewOutcome = await call(this.http, \"POST\", \"/moderation/{kind}/{id}/resolve\", {\n params: { kind, id: item.id },\n body: { decision, revision: item.revision, ...(reason ? { reason } : {}) },\n });\n this.http.emit({ type: \"moderation.resolved\", kind, id: item.id, decision });\n return out;\n }\n}\n"],"mappings":";;AAaA,IAAa,IAAb,MAA8B;CACC;CAA7B,YAAY,GAA6B;EAAZ,KAAA,OAAA;CAAa;CAG1C,KAAK,GAAc,GAAyC;EAC1D,OAAO,EAAK,KAAK,MAAM,OAAO,oBAAoB;GAAE,OAAO,EAAE,GAAG,EAAE;GAAG;EAAO,CAAC;CAC/E;CAEA,MAAM,QAAQ,GAAkD,GAAoB,GAAyC;EAC3H,IAAM,IAAO,EAAK,MACZ,IAAqB,MAAM,EAAK,KAAK,MAAM,QAAQ,mCAAmC;GAC1F,QAAQ;IAAE;IAAM,IAAI,EAAK;GAAG;GAC5B,MAAM;IAAE;IAAU,UAAU,EAAK;IAAU,GAAI,IAAS,EAAE,UAAO,IAAI,CAAC;GAAG;EAC3E,CAAC;EAED,OADA,KAAK,KAAK,KAAK;GAAE,MAAM;GAAuB;GAAM,IAAI,EAAK;GAAI;EAAS,CAAC,GACpE;CACT;AACF"}
@@ -0,0 +1,47 @@
1
+ import { Poll, PollInput, PollOption, PollOptionPatch, PollUpdate } from '../generated/wire.js';
2
+ import { Http } from '../http.js';
3
+ import { MediaClient, NamedOptions } from '../media/client.js';
4
+ import { PageQuery } from '../route.js';
5
+ export interface PollQuery extends PageQuery {
6
+ language?: string;
7
+ /** Polls live in this month, YYYY-MM. */
8
+ month?: string;
9
+ /** Polls live on this day, YYYY-MM-DD. */
10
+ date?: string;
11
+ }
12
+ /** Site-wide polls: multiple choice or free text; staff write them (PollWrite). */
13
+ export declare class PollsClient {
14
+ private readonly http;
15
+ private readonly media;
16
+ constructor(http: Http, media: MediaClient);
17
+ /** Live polls, newest first. */
18
+ list(q?: PollQuery, signal?: AbortSignal): Promise<Poll[]>;
19
+ /** Every poll, scheduled and inactive ones included (PollWrite). */
20
+ adminList(q?: PollQuery, signal?: AbortSignal): Promise<Poll[]>;
21
+ /** A poll with the caller's vote or answer. */
22
+ get(id: string, signal?: AbortSignal): Promise<Poll>;
23
+ /** Creates a poll with its options (images are set once it exists). */
24
+ create(input: PollInput): Promise<Poll>;
25
+ /** Updates the given fields. */
26
+ update(id: string, patch: PollUpdate): Promise<Poll>;
27
+ /** Deletes the poll and its images. */
28
+ delete(id: string): Promise<void>;
29
+ /** Votes for an option of an open multiple-choice poll; a vote is final, and voting again changes nothing. */
30
+ vote(id: string, option: string): Promise<Poll>;
31
+ /** Stores or replaces the signed-in caller's answer to an open free-text poll. */
32
+ answer(id: string, text: string): Promise<Poll>;
33
+ /** Sets the question image to an inline image name of the poll's folder, or clears it; resolves with its URL. */
34
+ setImage(id: string, image: string | null): Promise<string | null>;
35
+ /** Uploads file to the poll's folder as the question image (null clears it). */
36
+ uploadImage(id: string, file: Blob | null, o?: NamedOptions): Promise<string | null>;
37
+ /** Adds an option, at the end unless position is given. */
38
+ addOption(id: string, option: PollOptionPatch): Promise<PollOption>;
39
+ updateOption(id: string, option: string, patch: PollOptionPatch): Promise<PollOption>;
40
+ /** Removes an option and its votes; a poll keeps at least two. */
41
+ deleteOption(id: string, option: string): Promise<void>;
42
+ /** Gives the options the positions of their order, patching those that moved. */
43
+ reorderOptions(id: string, options: readonly Pick<PollOption, "id" | "position">[]): Promise<void>;
44
+ setOptionImage(id: string, option: string, image: string | null): Promise<string | null>;
45
+ /** Uploads file to the poll's folder as the option's image (null clears it). */
46
+ uploadOptionImage(id: string, option: string, file: Blob | null, o?: NamedOptions): Promise<string | null>;
47
+ }
@@ -0,0 +1,148 @@
1
+ import { call as e } from "../route.js";
2
+ //#region src/client/content/polls.ts
3
+ var t = class {
4
+ http;
5
+ media;
6
+ constructor(e, t) {
7
+ this.http = e, this.media = t;
8
+ }
9
+ list(t = {}, n) {
10
+ return e(this.http, "GET", "/polls", {
11
+ query: t,
12
+ signal: n
13
+ });
14
+ }
15
+ adminList(t = {}, n) {
16
+ return e(this.http, "GET", "/polls/admin", {
17
+ query: t,
18
+ signal: n
19
+ });
20
+ }
21
+ get(t, n) {
22
+ return e(this.http, "GET", "/polls/{id}", {
23
+ params: { id: t },
24
+ signal: n
25
+ });
26
+ }
27
+ async create(t) {
28
+ let n = await e(this.http, "POST", "/polls", { body: t });
29
+ return this.http.emit({
30
+ type: "poll.created",
31
+ poll: n
32
+ }), n;
33
+ }
34
+ async update(t, n) {
35
+ let r = await e(this.http, "PATCH", "/polls/{id}", {
36
+ params: { id: t },
37
+ body: n
38
+ });
39
+ return this.http.emit({
40
+ type: "poll.updated",
41
+ poll: r
42
+ }), r;
43
+ }
44
+ async delete(t) {
45
+ await e(this.http, "DELETE", "/polls/{id}", { params: { id: t } }), this.http.emit({
46
+ type: "poll.deleted",
47
+ id: t
48
+ });
49
+ }
50
+ async vote(t, n) {
51
+ let r = await e(this.http, "POST", "/polls/{id}/vote", {
52
+ params: { id: t },
53
+ body: { option_id: n }
54
+ });
55
+ return this.http.emit({
56
+ type: "poll.updated",
57
+ poll: r
58
+ }), r;
59
+ }
60
+ async answer(t, n) {
61
+ let r = await e(this.http, "POST", "/polls/{id}/answer", {
62
+ params: { id: t },
63
+ body: { text: n }
64
+ });
65
+ return this.http.emit({
66
+ type: "poll.updated",
67
+ poll: r
68
+ }), r;
69
+ }
70
+ async setImage(t, n) {
71
+ let r = await e(this.http, "PUT", "/polls/{id}/image", {
72
+ params: { id: t },
73
+ body: { image: n ?? "" }
74
+ });
75
+ return this.http.emit({
76
+ type: "poll.changed",
77
+ id: t
78
+ }), r.image_url;
79
+ }
80
+ async uploadImage(e, t, n) {
81
+ return this.setImage(e, t ? (await this.media.uploadNamed(this.media.pollRef(e), t, n)).name : null);
82
+ }
83
+ async addOption(t, n) {
84
+ let r = await e(this.http, "POST", "/polls/{id}/options", {
85
+ params: { id: t },
86
+ body: n
87
+ });
88
+ return this.http.emit({
89
+ type: "poll.changed",
90
+ id: t
91
+ }), r;
92
+ }
93
+ async updateOption(t, n, r) {
94
+ let i = await e(this.http, "PATCH", "/polls/{id}/options/{oid}", {
95
+ params: {
96
+ id: t,
97
+ oid: n
98
+ },
99
+ body: r
100
+ });
101
+ return this.http.emit({
102
+ type: "poll.changed",
103
+ id: t
104
+ }), i;
105
+ }
106
+ async deleteOption(t, n) {
107
+ await e(this.http, "DELETE", "/polls/{id}/options/{oid}", { params: {
108
+ id: t,
109
+ oid: n
110
+ } }), this.http.emit({
111
+ type: "poll.changed",
112
+ id: t
113
+ });
114
+ }
115
+ async reorderOptions(t, n) {
116
+ for (let [r, i] of n.entries()) i.position !== r && await e(this.http, "PATCH", "/polls/{id}/options/{oid}", {
117
+ params: {
118
+ id: t,
119
+ oid: i.id
120
+ },
121
+ body: { position: r }
122
+ });
123
+ this.http.emit({
124
+ type: "poll.changed",
125
+ id: t
126
+ });
127
+ }
128
+ async setOptionImage(t, n, r) {
129
+ let i = await e(this.http, "PUT", "/polls/{id}/options/{oid}/image", {
130
+ params: {
131
+ id: t,
132
+ oid: n
133
+ },
134
+ body: { image: r ?? "" }
135
+ });
136
+ return this.http.emit({
137
+ type: "poll.changed",
138
+ id: t
139
+ }), i.image_url;
140
+ }
141
+ async uploadOptionImage(e, t, n, r) {
142
+ return this.setOptionImage(e, t, n ? (await this.media.uploadNamed(this.media.pollRef(e), n, r)).name : null);
143
+ }
144
+ };
145
+ //#endregion
146
+ export { t as PollsClient };
147
+
148
+ //# sourceMappingURL=polls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"polls.js","names":[],"sources":["../../../src/client/content/polls.ts"],"sourcesContent":["import type { Poll, PollImage, PollInput, PollOption, PollOptionPatch, PollUpdate } from \"../generated/wire.js\";\nimport type { Http } from \"../http.js\";\nimport type { MediaClient, NamedOptions } from \"../media/client.js\";\nimport { call, type PageQuery } from \"../route.js\";\n\nexport interface PollQuery extends PageQuery {\n language?: string;\n /** Polls live in this month, YYYY-MM. */\n month?: string;\n /** Polls live on this day, YYYY-MM-DD. */\n date?: string;\n}\n\n/** Site-wide polls: multiple choice or free text; staff write them (PollWrite). */\nexport class PollsClient {\n constructor(\n private readonly http: Http,\n private readonly media: MediaClient,\n ) {}\n\n /** Live polls, newest first. */\n list(q: PollQuery = {}, signal?: AbortSignal): Promise<Poll[]> {\n return call(this.http, \"GET\", \"/polls\", { query: q, signal });\n }\n /** Every poll, scheduled and inactive ones included (PollWrite). */\n adminList(q: PollQuery = {}, signal?: AbortSignal): Promise<Poll[]> {\n return call(this.http, \"GET\", \"/polls/admin\", { query: q, signal });\n }\n /** A poll with the caller's vote or answer. */\n get(id: string, signal?: AbortSignal): Promise<Poll> {\n return call(this.http, \"GET\", \"/polls/{id}\", { params: { id }, signal });\n }\n /** Creates a poll with its options (images are set once it exists). */\n async create(input: PollInput): Promise<Poll> {\n const poll: Poll = await call(this.http, \"POST\", \"/polls\", { body: input });\n this.http.emit({ type: \"poll.created\", poll });\n return poll;\n }\n /** Updates the given fields. */\n async update(id: string, patch: PollUpdate): Promise<Poll> {\n const poll: Poll = await call(this.http, \"PATCH\", \"/polls/{id}\", { params: { id }, body: patch });\n this.http.emit({ type: \"poll.updated\", poll });\n return poll;\n }\n /** Deletes the poll and its images. */\n async delete(id: string): Promise<void> {\n await call(this.http, \"DELETE\", \"/polls/{id}\", { params: { id } });\n this.http.emit({ type: \"poll.deleted\", id });\n }\n /** Votes for an option of an open multiple-choice poll; a vote is final, and voting again changes nothing. */\n async vote(id: string, option: string): Promise<Poll> {\n const poll: Poll = await call(this.http, \"POST\", \"/polls/{id}/vote\", { params: { id }, body: { option_id: option } });\n this.http.emit({ type: \"poll.updated\", poll });\n return poll;\n }\n /** Stores or replaces the signed-in caller's answer to an open free-text poll. */\n async answer(id: string, text: string): Promise<Poll> {\n const poll: Poll = await call(this.http, \"POST\", \"/polls/{id}/answer\", { params: { id }, body: { text } });\n this.http.emit({ type: \"poll.updated\", poll });\n return poll;\n }\n /** Sets the question image to an inline image name of the poll's folder, or clears it; resolves with its URL. */\n async setImage(id: string, image: string | null): Promise<string | null> {\n const r: PollImage = await call(this.http, \"PUT\", \"/polls/{id}/image\", { params: { id }, body: { image: image ?? \"\" } });\n this.http.emit({ type: \"poll.changed\", id });\n return r.image_url;\n }\n /** Uploads file to the poll's folder as the question image (null clears it). */\n async uploadImage(id: string, file: Blob | null, o?: NamedOptions): Promise<string | null> {\n return this.setImage(id, file ? (await this.media.uploadNamed(this.media.pollRef(id), file, o)).name : null);\n }\n /** Adds an option, at the end unless position is given. */\n async addOption(id: string, option: PollOptionPatch): Promise<PollOption> {\n const o: PollOption = await call(this.http, \"POST\", \"/polls/{id}/options\", { params: { id }, body: option });\n this.http.emit({ type: \"poll.changed\", id });\n return o;\n }\n async updateOption(id: string, option: string, patch: PollOptionPatch): Promise<PollOption> {\n const o: PollOption = await call(this.http, \"PATCH\", \"/polls/{id}/options/{oid}\", { params: { id, oid: option }, body: patch });\n this.http.emit({ type: \"poll.changed\", id });\n return o;\n }\n /** Removes an option and its votes; a poll keeps at least two. */\n async deleteOption(id: string, option: string): Promise<void> {\n await call(this.http, \"DELETE\", \"/polls/{id}/options/{oid}\", { params: { id, oid: option } });\n this.http.emit({ type: \"poll.changed\", id });\n }\n /** Gives the options the positions of their order, patching those that moved. */\n async reorderOptions(id: string, options: readonly Pick<PollOption, \"id\" | \"position\">[]): Promise<void> {\n for (const [position, o] of options.entries()) {\n if (o.position !== position) await call(this.http, \"PATCH\", \"/polls/{id}/options/{oid}\", { params: { id, oid: o.id }, body: { position } });\n }\n this.http.emit({ type: \"poll.changed\", id });\n }\n async setOptionImage(id: string, option: string, image: string | null): Promise<string | null> {\n const r: PollImage = await call(this.http, \"PUT\", \"/polls/{id}/options/{oid}/image\", { params: { id, oid: option }, body: { image: image ?? \"\" } });\n this.http.emit({ type: \"poll.changed\", id });\n return r.image_url;\n }\n /** Uploads file to the poll's folder as the option's image (null clears it). */\n async uploadOptionImage(id: string, option: string, file: Blob | null, o?: NamedOptions): Promise<string | null> {\n return this.setOptionImage(id, option, file ? (await this.media.uploadNamed(this.media.pollRef(id), file, o)).name : null);\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import { Post, PostInput } from '../generated/wire.js';
2
+ import { Http } from '../http.js';
3
+ import { MediaClient, NamedOptions } from '../media/client.js';
4
+ import { PageQuery } from '../route.js';
5
+ import { Reaction, Sort } from './types.js';
6
+ export interface PostQuery extends PageQuery {
7
+ language?: string;
8
+ sort?: Sort;
9
+ }
10
+ export interface PostAdminQuery extends PageQuery {
11
+ language?: string;
12
+ /** true: only drafts; false: only posts that are not drafts. */
13
+ draft?: boolean;
14
+ /** true: only deleted posts (with deleted_at); otherwise only live ones. */
15
+ deleted?: boolean;
16
+ /** Only posts whose title, excerpt or body contains this text, ignoring case. */
17
+ q?: string;
18
+ }
19
+ /** Posts: the published list, staff CRUD, search and restore, reactions, the cover and body images. */
20
+ export declare class PostsClient {
21
+ private readonly http;
22
+ private readonly media;
23
+ constructor(http: Http, media: MediaClient);
24
+ /** Published posts. */
25
+ list(q?: PostQuery, signal?: AbortSignal): Promise<Post[]>;
26
+ /** Every post for staff: drafts, scheduled, held and rejected ones included; deleted ones on their own; q searches (PostWrite). */
27
+ adminList(q?: PostAdminQuery, signal?: AbortSignal): Promise<Post[]>;
28
+ get(id: string, signal?: AbortSignal): Promise<Post>;
29
+ /** Creates a post (PostWrite); moderation "held" when the moderator holds it. */
30
+ create(input: PostInput): Promise<Post>;
31
+ /** Updates the given fields (PostWrite). */
32
+ update(id: string, input: PostInput): Promise<Post>;
33
+ delete(id: string): Promise<void>;
34
+ /** Restores a deleted post as it was (PostWrite); conflict when a live post took its slug. */
35
+ restore(id: string): Promise<Post>;
36
+ /** Sets the caller's reaction to a published post; resolves with the post's new totals. */
37
+ react(id: string, value: Reaction): Promise<Post>;
38
+ /** Sets the cover to an inline image name ("i-{uuid}") of the post's folder, or clears it; resolves with its URL. */
39
+ setCover(id: string, image: string | null): Promise<string | null>;
40
+ /** Uploads file to the post's folder and makes it the cover (null clears it); resolves with its URL. */
41
+ uploadCover(id: string, file: Blob | null, o?: NamedOptions): Promise<string | null>;
42
+ /** The public URL of an inline image of the post's folder, to place in its body. */
43
+ imageURL(id: string, image: string, signal?: AbortSignal): Promise<string>;
44
+ }
@@ -0,0 +1,91 @@
1
+ import { call as e } from "../route.js";
2
+ import { reactionVerb as t } from "./types.js";
3
+ //#region src/client/content/posts.ts
4
+ var n = class {
5
+ http;
6
+ media;
7
+ constructor(e, t) {
8
+ this.http = e, this.media = t;
9
+ }
10
+ list(t = {}, n) {
11
+ return e(this.http, "GET", "/posts", {
12
+ query: t,
13
+ signal: n
14
+ });
15
+ }
16
+ adminList(t = {}, n) {
17
+ return e(this.http, "GET", "/posts/admin", {
18
+ query: t,
19
+ signal: n
20
+ });
21
+ }
22
+ get(t, n) {
23
+ return e(this.http, "GET", "/posts/{id}", {
24
+ params: { id: t },
25
+ signal: n
26
+ });
27
+ }
28
+ async create(t) {
29
+ let n = await e(this.http, "POST", "/posts", { body: t });
30
+ return this.http.emit({
31
+ type: "post.created",
32
+ post: n
33
+ }), n;
34
+ }
35
+ async update(t, n) {
36
+ let r = await e(this.http, "PATCH", "/posts/{id}", {
37
+ params: { id: t },
38
+ body: n
39
+ });
40
+ return this.http.emit({
41
+ type: "post.updated",
42
+ post: r
43
+ }), r;
44
+ }
45
+ async delete(t) {
46
+ await e(this.http, "DELETE", "/posts/{id}", { params: { id: t } }), this.http.emit({
47
+ type: "post.deleted",
48
+ id: t
49
+ });
50
+ }
51
+ async restore(t) {
52
+ let n = await e(this.http, "POST", "/posts/{id}/restore", { params: { id: t } });
53
+ return this.http.emit({
54
+ type: "post.restored",
55
+ post: n
56
+ }), n;
57
+ }
58
+ async react(n, r) {
59
+ let i = await e(this.http, "POST", `/posts/{id}/${t(r)}`, { params: { id: n } });
60
+ return this.http.emit({
61
+ type: "post.updated",
62
+ post: i
63
+ }), i;
64
+ }
65
+ async setCover(t, n) {
66
+ let r = await e(this.http, "PUT", "/posts/{id}/cover", {
67
+ params: { id: t },
68
+ body: { image: n ?? "" }
69
+ });
70
+ return this.http.emit({
71
+ type: "post.changed",
72
+ id: t
73
+ }), r.cover_url;
74
+ }
75
+ async uploadCover(e, t, n) {
76
+ if (!t) return this.setCover(e, null);
77
+ let r = await this.media.uploadNamed(this.media.postRef(e), t, n);
78
+ return this.setCover(e, r.name);
79
+ }
80
+ async imageURL(t, n, r) {
81
+ return (await e(this.http, "POST", "/posts/{id}/images", {
82
+ params: { id: t },
83
+ body: { image: n },
84
+ signal: r
85
+ })).url;
86
+ }
87
+ };
88
+ //#endregion
89
+ export { n as PostsClient };
90
+
91
+ //# sourceMappingURL=posts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"posts.js","names":[],"sources":["../../../src/client/content/posts.ts"],"sourcesContent":["import type { InlineImage, Post, PostCover, PostInput } from \"../generated/wire.js\";\nimport type { Http } from \"../http.js\";\nimport type { MediaClient, NamedOptions } from \"../media/client.js\";\nimport { call, type PageQuery } from \"../route.js\";\nimport { reactionVerb, type Reaction, type Sort } from \"./types.js\";\n\nexport interface PostQuery extends PageQuery {\n language?: string;\n sort?: Sort;\n}\n\nexport interface PostAdminQuery extends PageQuery {\n language?: string;\n /** true: only drafts; false: only posts that are not drafts. */\n draft?: boolean;\n /** true: only deleted posts (with deleted_at); otherwise only live ones. */\n deleted?: boolean;\n /** Only posts whose title, excerpt or body contains this text, ignoring case. */\n q?: string;\n}\n\n/** Posts: the published list, staff CRUD, search and restore, reactions, the cover and body images. */\nexport class PostsClient {\n constructor(\n private readonly http: Http,\n private readonly media: MediaClient,\n ) {}\n\n /** Published posts. */\n list(q: PostQuery = {}, signal?: AbortSignal): Promise<Post[]> {\n return call(this.http, \"GET\", \"/posts\", { query: q, signal });\n }\n /** Every post for staff: drafts, scheduled, held and rejected ones included; deleted ones on their own; q searches (PostWrite). */\n adminList(q: PostAdminQuery = {}, signal?: AbortSignal): Promise<Post[]> {\n return call(this.http, \"GET\", \"/posts/admin\", { query: q, signal });\n }\n get(id: string, signal?: AbortSignal): Promise<Post> {\n return call(this.http, \"GET\", \"/posts/{id}\", { params: { id }, signal });\n }\n /** Creates a post (PostWrite); moderation \"held\" when the moderator holds it. */\n async create(input: PostInput): Promise<Post> {\n const post: Post = await call(this.http, \"POST\", \"/posts\", { body: input });\n this.http.emit({ type: \"post.created\", post });\n return post;\n }\n /** Updates the given fields (PostWrite). */\n async update(id: string, input: PostInput): Promise<Post> {\n const post: Post = await call(this.http, \"PATCH\", \"/posts/{id}\", { params: { id }, body: input });\n this.http.emit({ type: \"post.updated\", post });\n return post;\n }\n async delete(id: string): Promise<void> {\n await call(this.http, \"DELETE\", \"/posts/{id}\", { params: { id } });\n this.http.emit({ type: \"post.deleted\", id });\n }\n /** Restores a deleted post as it was (PostWrite); conflict when a live post took its slug. */\n async restore(id: string): Promise<Post> {\n const post: Post = await call(this.http, \"POST\", \"/posts/{id}/restore\", { params: { id } });\n this.http.emit({ type: \"post.restored\", post });\n return post;\n }\n /** Sets the caller's reaction to a published post; resolves with the post's new totals. */\n async react(id: string, value: Reaction): Promise<Post> {\n const post: Post = await call(this.http, \"POST\", `/posts/{id}/${reactionVerb(value)}` as const, { params: { id } });\n this.http.emit({ type: \"post.updated\", post });\n return post;\n }\n /** Sets the cover to an inline image name (\"i-{uuid}\") of the post's folder, or clears it; resolves with its URL. */\n async setCover(id: string, image: string | null): Promise<string | null> {\n const r: PostCover = await call(this.http, \"PUT\", \"/posts/{id}/cover\", { params: { id }, body: { image: image ?? \"\" } });\n this.http.emit({ type: \"post.changed\", id });\n return r.cover_url;\n }\n /** Uploads file to the post's folder and makes it the cover (null clears it); resolves with its URL. */\n async uploadCover(id: string, file: Blob | null, o?: NamedOptions): Promise<string | null> {\n if (!file) return this.setCover(id, null);\n const up = await this.media.uploadNamed(this.media.postRef(id), file, o);\n return this.setCover(id, up.name);\n }\n /** The public URL of an inline image of the post's folder, to place in its body. */\n async imageURL(id: string, image: string, signal?: AbortSignal): Promise<string> {\n const r: InlineImage = await call(this.http, \"POST\", \"/posts/{id}/images\", { params: { id }, body: { image }, signal });\n return r.url;\n }\n}\n"],"mappings":";;;AAsBA,IAAa,IAAb,MAAyB;CAEJ;CACA;CAFnB,YACE,GACA,GACA;EADiB,AADA,KAAA,OAAA,GACA,KAAA,QAAA;CAChB;CAGH,KAAK,IAAe,CAAC,GAAG,GAAuC;EAC7D,OAAO,EAAK,KAAK,MAAM,OAAO,UAAU;GAAE,OAAO;GAAG;EAAO,CAAC;CAC9D;CAEA,UAAU,IAAoB,CAAC,GAAG,GAAuC;EACvE,OAAO,EAAK,KAAK,MAAM,OAAO,gBAAgB;GAAE,OAAO;GAAG;EAAO,CAAC;CACpE;CACA,IAAI,GAAY,GAAqC;EACnD,OAAO,EAAK,KAAK,MAAM,OAAO,eAAe;GAAE,QAAQ,EAAE,MAAG;GAAG;EAAO,CAAC;CACzE;CAEA,MAAM,OAAO,GAAiC;EAC5C,IAAM,IAAa,MAAM,EAAK,KAAK,MAAM,QAAQ,UAAU,EAAE,MAAM,EAAM,CAAC;EAE1E,OADA,KAAK,KAAK,KAAK;GAAE,MAAM;GAAgB;EAAK,CAAC,GACtC;CACT;CAEA,MAAM,OAAO,GAAY,GAAiC;EACxD,IAAM,IAAa,MAAM,EAAK,KAAK,MAAM,SAAS,eAAe;GAAE,QAAQ,EAAE,MAAG;GAAG,MAAM;EAAM,CAAC;EAEhG,OADA,KAAK,KAAK,KAAK;GAAE,MAAM;GAAgB;EAAK,CAAC,GACtC;CACT;CACA,MAAM,OAAO,GAA2B;EAEtC,AADA,MAAM,EAAK,KAAK,MAAM,UAAU,eAAe,EAAE,QAAQ,EAAE,MAAG,EAAE,CAAC,GACjE,KAAK,KAAK,KAAK;GAAE,MAAM;GAAgB;EAAG,CAAC;CAC7C;CAEA,MAAM,QAAQ,GAA2B;EACvC,IAAM,IAAa,MAAM,EAAK,KAAK,MAAM,QAAQ,uBAAuB,EAAE,QAAQ,EAAE,MAAG,EAAE,CAAC;EAE1F,OADA,KAAK,KAAK,KAAK;GAAE,MAAM;GAAiB;EAAK,CAAC,GACvC;CACT;CAEA,MAAM,MAAM,GAAY,GAAgC;EACtD,IAAM,IAAa,MAAM,EAAK,KAAK,MAAM,QAAQ,eAAe,EAAa,CAAK,KAAc,EAAE,QAAQ,EAAE,MAAG,EAAE,CAAC;EAElH,OADA,KAAK,KAAK,KAAK;GAAE,MAAM;GAAgB;EAAK,CAAC,GACtC;CACT;CAEA,MAAM,SAAS,GAAY,GAA8C;EACvE,IAAM,IAAe,MAAM,EAAK,KAAK,MAAM,OAAO,qBAAqB;GAAE,QAAQ,EAAE,MAAG;GAAG,MAAM,EAAE,OAAO,KAAS,GAAG;EAAE,CAAC;EAEvH,OADA,KAAK,KAAK,KAAK;GAAE,MAAM;GAAgB;EAAG,CAAC,GACpC,EAAE;CACX;CAEA,MAAM,YAAY,GAAY,GAAmB,GAA0C;EACzF,IAAI,CAAC,GAAM,OAAO,KAAK,SAAS,GAAI,IAAI;EACxC,IAAM,IAAK,MAAM,KAAK,MAAM,YAAY,KAAK,MAAM,QAAQ,CAAE,GAAG,GAAM,CAAC;EACvE,OAAO,KAAK,SAAS,GAAI,EAAG,IAAI;CAClC;CAEA,MAAM,SAAS,GAAY,GAAe,GAAuC;EAE/E,QAAO,MADsB,EAAK,KAAK,MAAM,QAAQ,sBAAsB;GAAE,QAAQ,EAAE,MAAG;GAAG,MAAM,EAAE,SAAM;GAAG;EAAO,CAAC,EAAA,CAC7G;CACX;AACF"}
@@ -0,0 +1,12 @@
1
+ import { ReactionCounts, RefBody } from '../generated/wire.js';
2
+ import { Http } from '../http.js';
3
+ import { Reaction } from './types.js';
4
+ /** Likes and dislikes of an item (a host kind, or "post"). */
5
+ export declare class ReactionsClient {
6
+ private readonly http;
7
+ constructor(http: Http);
8
+ /** The item's counts and the caller's own reaction. */
9
+ get(ref: RefBody, signal?: AbortSignal): Promise<ReactionCounts>;
10
+ /** Sets the caller's reaction (0 clears it); resolves with the new counts. */
11
+ set(ref: RefBody, value: Reaction): Promise<ReactionCounts>;
12
+ }
@@ -0,0 +1,36 @@
1
+ import { call as e } from "../route.js";
2
+ import { reactionVerb as t } from "./types.js";
3
+ //#region src/client/content/reactions.ts
4
+ var n = class {
5
+ http;
6
+ constructor(e) {
7
+ this.http = e;
8
+ }
9
+ get(t, n) {
10
+ return e(this.http, "GET", "/{kind}/{id}/reaction", {
11
+ params: {
12
+ kind: t.kind,
13
+ id: t.id
14
+ },
15
+ signal: n
16
+ });
17
+ }
18
+ async set(n, r) {
19
+ let i = await e(this.http, "POST", `/{kind}/{id}/${t(r)}`, { params: {
20
+ kind: n.kind,
21
+ id: n.id
22
+ } });
23
+ return this.http.emit({
24
+ type: "reaction.changed",
25
+ ref: {
26
+ kind: n.kind,
27
+ id: n.id
28
+ },
29
+ counts: i
30
+ }), i;
31
+ }
32
+ };
33
+ //#endregion
34
+ export { n as ReactionsClient };
35
+
36
+ //# sourceMappingURL=reactions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reactions.js","names":[],"sources":["../../../src/client/content/reactions.ts"],"sourcesContent":["import type { ReactionCounts, RefBody } from \"../generated/wire.js\";\nimport type { Http } from \"../http.js\";\nimport { call } from \"../route.js\";\nimport { reactionVerb, type Reaction } from \"./types.js\";\n\n/** Likes and dislikes of an item (a host kind, or \"post\"). */\nexport class ReactionsClient {\n constructor(private readonly http: Http) {}\n\n /** The item's counts and the caller's own reaction. */\n get(ref: RefBody, signal?: AbortSignal): Promise<ReactionCounts> {\n return call(this.http, \"GET\", \"/{kind}/{id}/reaction\", { params: { kind: ref.kind, id: ref.id }, signal });\n }\n /** Sets the caller's reaction (0 clears it); resolves with the new counts. */\n async set(ref: RefBody, value: Reaction): Promise<ReactionCounts> {\n const counts: ReactionCounts = await call(this.http, \"POST\", `/{kind}/{id}/${reactionVerb(value)}` as const, { params: { kind: ref.kind, id: ref.id } });\n this.http.emit({ type: \"reaction.changed\", ref: { kind: ref.kind, id: ref.id }, counts });\n return counts;\n }\n}\n"],"mappings":";;;AAMA,IAAa,IAAb,MAA6B;CACE;CAA7B,YAAY,GAA6B;EAAZ,KAAA,OAAA;CAAa;CAG1C,IAAI,GAAc,GAA+C;EAC/D,OAAO,EAAK,KAAK,MAAM,OAAO,yBAAyB;GAAE,QAAQ;IAAE,MAAM,EAAI;IAAM,IAAI,EAAI;GAAG;GAAG;EAAO,CAAC;CAC3G;CAEA,MAAM,IAAI,GAAc,GAA0C;EAChE,IAAM,IAAyB,MAAM,EAAK,KAAK,MAAM,QAAQ,gBAAgB,EAAa,CAAK,KAAc,EAAE,QAAQ;GAAE,MAAM,EAAI;GAAM,IAAI,EAAI;EAAG,EAAE,CAAC;EAEvJ,OADA,KAAK,KAAK,KAAK;GAAE,MAAM;GAAoB,KAAK;IAAE,MAAM,EAAI;IAAM,IAAI,EAAI;GAAG;GAAG;EAAO,CAAC,GACjF;CACT;AACF"}
@@ -0,0 +1,91 @@
1
+ import { CommentBan, CommentStanding, Comment, Poll, Post, ReactionCounts, RefBody, ResolveInput } from '../generated/wire.js';
2
+ /** A reaction: like 1, dislike -1, none 0. */
3
+ export type Reaction = -1 | 0 | 1;
4
+ /** The route verb that sets a reaction. */
5
+ export declare function reactionVerb(value: Reaction): "like" | "dislike" | "neutral";
6
+ /** Comment and post order: newest (the default), likes (most liked) or best (Wilson lower bound). */
7
+ export type Sort = "newest" | "likes" | "best";
8
+ /** A ban route family: "owner" bans from the caller's own content, "global" from the whole site. */
9
+ export type BanScope = CommentStanding["ban_scopes"][number];
10
+ /** What the review queue holds. */
11
+ export type HeldKind = "comment" | "post";
12
+ /** A reviewer's decision on a held item. */
13
+ export type Decision = Exclude<ResolveInput["decision"], "review">;
14
+ /** A content-module mutation made through the client. */
15
+ export type ContentChange = {
16
+ type: "post.created";
17
+ post: Post;
18
+ } | {
19
+ type: "post.updated";
20
+ post: Post;
21
+ }
22
+ /** The cover changed: refetch the post. */
23
+ | {
24
+ type: "post.changed";
25
+ id: string;
26
+ } | {
27
+ type: "post.deleted";
28
+ id: string;
29
+ } | {
30
+ type: "post.restored";
31
+ post: Post;
32
+ }
33
+ /** ref is the commented item. */
34
+ | {
35
+ type: "comment.created";
36
+ ref: RefBody;
37
+ comment: Comment;
38
+ } | {
39
+ type: "comment.updated";
40
+ comment: Comment;
41
+ } | {
42
+ type: "comment.deleted";
43
+ id: string;
44
+ } | {
45
+ type: "comment.restored";
46
+ id: string;
47
+ } | {
48
+ type: "comment.reacted";
49
+ id: string;
50
+ counts: ReactionCounts;
51
+ } | {
52
+ type: "reaction.changed";
53
+ ref: RefBody;
54
+ counts: ReactionCounts;
55
+ } | {
56
+ type: "favorite.changed";
57
+ ref: RefBody;
58
+ favorited: boolean;
59
+ count: number;
60
+ }
61
+ /** Created, updated, voted or answered: the poll as the server now answers it. */
62
+ | {
63
+ type: "poll.created";
64
+ poll: Poll;
65
+ } | {
66
+ type: "poll.updated";
67
+ poll: Poll;
68
+ }
69
+ /** An option or image changed: refetch the poll. */
70
+ | {
71
+ type: "poll.changed";
72
+ id: string;
73
+ } | {
74
+ type: "poll.deleted";
75
+ id: string;
76
+ } | {
77
+ type: "ban.saved";
78
+ scope: BanScope;
79
+ ban: CommentBan;
80
+ } | {
81
+ type: "ban.lifted";
82
+ scope: BanScope;
83
+ user: string;
84
+ } | {
85
+ type: "moderation.resolved";
86
+ kind: HeldKind;
87
+ id: string;
88
+ decision: Decision;
89
+ } | {
90
+ type: "taxonomy.changed";
91
+ };
@@ -0,0 +1,8 @@
1
+ //#region src/client/content/types.ts
2
+ function e(e) {
3
+ return e === 1 ? "like" : e === -1 ? "dislike" : "neutral";
4
+ }
5
+ //#endregion
6
+ export { e as reactionVerb };
7
+
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","names":[],"sources":["../../../src/client/content/types.ts"],"sourcesContent":["import type { CommentBan, CommentStanding, Comment, Poll, Post, ReactionCounts, RefBody, ResolveInput } from \"../generated/wire.js\";\n\n/** A reaction: like 1, dislike -1, none 0. */\nexport type Reaction = -1 | 0 | 1;\n\n/** The route verb that sets a reaction. */\nexport function reactionVerb(value: Reaction): \"like\" | \"dislike\" | \"neutral\" {\n return value === 1 ? \"like\" : value === -1 ? \"dislike\" : \"neutral\";\n}\n\n/** Comment and post order: newest (the default), likes (most liked) or best (Wilson lower bound). */\nexport type Sort = \"newest\" | \"likes\" | \"best\";\n\n/** A ban route family: \"owner\" bans from the caller's own content, \"global\" from the whole site. */\nexport type BanScope = CommentStanding[\"ban_scopes\"][number];\n\n/** What the review queue holds. */\nexport type HeldKind = \"comment\" | \"post\";\n\n/** A reviewer's decision on a held item. */\nexport type Decision = Exclude<ResolveInput[\"decision\"], \"review\">;\n\n/** A content-module mutation made through the client. */\nexport type ContentChange =\n | { type: \"post.created\"; post: Post }\n | { type: \"post.updated\"; post: Post }\n /** The cover changed: refetch the post. */\n | { type: \"post.changed\"; id: string }\n | { type: \"post.deleted\"; id: string }\n | { type: \"post.restored\"; post: Post }\n /** ref is the commented item. */\n | { type: \"comment.created\"; ref: RefBody; comment: Comment }\n | { type: \"comment.updated\"; comment: Comment }\n | { type: \"comment.deleted\"; id: string }\n | { type: \"comment.restored\"; id: string }\n | { type: \"comment.reacted\"; id: string; counts: ReactionCounts }\n | { type: \"reaction.changed\"; ref: RefBody; counts: ReactionCounts }\n | { type: \"favorite.changed\"; ref: RefBody; favorited: boolean; count: number }\n /** Created, updated, voted or answered: the poll as the server now answers it. */\n | { type: \"poll.created\"; poll: Poll }\n | { type: \"poll.updated\"; poll: Poll }\n /** An option or image changed: refetch the poll. */\n | { type: \"poll.changed\"; id: string }\n | { type: \"poll.deleted\"; id: string }\n | { type: \"ban.saved\"; scope: BanScope; ban: CommentBan }\n | { type: \"ban.lifted\"; scope: BanScope; user: string }\n | { type: \"moderation.resolved\"; kind: HeldKind; id: string; decision: Decision }\n | { type: \"taxonomy.changed\" };\n"],"mappings":";AAMA,SAAgB,EAAa,GAAiD;CAC5E,OAAO,MAAU,IAAI,SAAS,MAAU,KAAK,YAAY;AAC3D"}
@@ -0,0 +1,32 @@
1
+ import { Crop, Edit } from './generated/wire.js';
2
+ /** Clockwise degrees. */
3
+ export type Rotation = 0 | 90 | 180 | 270;
4
+ export interface Size {
5
+ width: number;
6
+ height: number;
7
+ }
8
+ /**
9
+ * Fits rect (original pixels) inside source as whole pixels. With aspect (the
10
+ * edited image's width/height; with a 90/270 rotation the crop is its
11
+ * transpose) the height follows the width exactly as the server derives it.
12
+ */
13
+ export declare function constrainCrop(rect: Crop, source: Size, aspect?: number, rotate?: Rotation): Crop;
14
+ /**
15
+ * Maps a rect on the image shown at display size to original pixels. With a
16
+ * rotation, display is the rotated image (as a cropper shows it) and the rect
17
+ * is mapped back through the rotation.
18
+ */
19
+ export declare function toOriginal(rect: Crop, display: Size, source: Size, rotate?: Rotation): Crop;
20
+ /** The image's size after a clockwise rotation. */
21
+ export declare function editedSize(source: Size, rotate?: Rotation): Size;
22
+ /** A rect in original pixels as it lies on the image turned clockwise by rotate. */
23
+ export declare function toRotated(r: Crop, source: Size, rotate: Rotation): Crop;
24
+ /** Inverse of toRotated: a rect on the rotated image back in original pixels. */
25
+ export declare function fromRotated(r: Crop, source: Size, rotate: Rotation): Crop;
26
+ /** The largest centred crop (at aspect, if any). */
27
+ export declare function centeredCrop(source: Size, aspect?: number, rotate?: Rotation): Crop;
28
+ /** The edit for a crop and rotation; null when it changes nothing. */
29
+ export declare function editOf(crop: Crop | null, source: Size, rotate?: Rotation): Edit | null;
30
+ /** Whether two edits are the same value (null and an empty edit are). */
31
+ export declare function sameEdit(a: Edit | null | undefined, b: Edit | null | undefined): boolean;
32
+ export declare function rotation(deg: number): Rotation;