@eightyfourthousand/data-access 2026.4.0 → 2026.4.2

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 (345) hide show
  1. package/index.js +18 -0
  2. package/index.js.map +1 -0
  3. package/lib/auth.d.ts +59 -0
  4. package/lib/auth.js +134 -0
  5. package/lib/auth.js.map +1 -0
  6. package/lib/bibliography.d.ts +9 -0
  7. package/lib/bibliography.js +30 -0
  8. package/lib/bibliography.js.map +1 -0
  9. package/lib/client-browser.d.ts +1 -0
  10. package/lib/client-browser.js +10 -0
  11. package/lib/client-browser.js.map +1 -0
  12. package/lib/client-server.d.ts +4 -0
  13. package/lib/client-server.js +19 -0
  14. package/lib/client-server.js.map +1 -0
  15. package/lib/client-ssr.d.ts +1 -0
  16. package/lib/client-ssr.js +23 -0
  17. package/lib/client-ssr.js.map +1 -0
  18. package/lib/client-token.d.ts +7 -0
  19. package/lib/client-token.js +21 -0
  20. package/lib/client-token.js.map +1 -0
  21. package/lib/feedback.d.ts +6 -0
  22. package/lib/feedback.js +45 -0
  23. package/lib/feedback.js.map +1 -0
  24. package/lib/folio.d.ts +11 -0
  25. package/lib/folio.js +31 -0
  26. package/lib/folio.js.map +1 -0
  27. package/lib/glossary/batch.d.ts +5 -0
  28. package/lib/glossary/batch.js +22 -0
  29. package/lib/glossary/batch.js.map +1 -0
  30. package/lib/glossary/index.js +5 -0
  31. package/lib/glossary/index.js.map +1 -0
  32. package/lib/glossary/instance.d.ts +10 -0
  33. package/lib/glossary/instance.js +28 -0
  34. package/lib/glossary/instance.js.map +1 -0
  35. package/lib/glossary/landing.d.ts +5 -0
  36. package/lib/glossary/landing.js +32 -0
  37. package/lib/glossary/landing.js.map +1 -0
  38. package/lib/glossary/pagination.d.ts +55 -0
  39. package/lib/glossary/pagination.js +254 -0
  40. package/lib/glossary/pagination.js.map +1 -0
  41. package/lib/imprint.d.ts +10 -0
  42. package/lib/imprint.js +23 -0
  43. package/lib/imprint.js.map +1 -0
  44. package/lib/library.d.ts +58 -0
  45. package/lib/library.js +118 -0
  46. package/lib/library.js.map +1 -0
  47. package/lib/local-storage.d.ts +10 -0
  48. package/lib/local-storage.js +25 -0
  49. package/lib/local-storage.js.map +1 -0
  50. package/lib/lookup-entity.d.ts +7 -0
  51. package/lib/lookup-entity.js +93 -0
  52. package/lib/lookup-entity.js.map +1 -0
  53. package/lib/panel-url.d.ts +10 -0
  54. package/lib/panel-url.js +23 -0
  55. package/lib/panel-url.js.map +1 -0
  56. package/lib/passage/batch.d.ts +17 -0
  57. package/lib/passage/batch.js +155 -0
  58. package/lib/passage/batch.js.map +1 -0
  59. package/lib/passage/index.js +6 -0
  60. package/lib/passage/index.js.map +1 -0
  61. package/lib/passage/pagination.d.ts +43 -0
  62. package/lib/passage/pagination.js +167 -0
  63. package/lib/passage/pagination.js.map +1 -0
  64. package/lib/passage/read.d.ts +15 -0
  65. package/lib/passage/read.js +59 -0
  66. package/lib/passage/read.js.map +1 -0
  67. package/lib/passage/replace-persistence.d.ts +46 -0
  68. package/lib/passage/replace-persistence.js +93 -0
  69. package/lib/passage/replace-persistence.js.map +1 -0
  70. package/lib/passage/save.d.ts +16 -0
  71. package/lib/passage/save.js +227 -0
  72. package/lib/passage/save.js.map +1 -0
  73. package/lib/proxy.d.ts +7 -0
  74. package/lib/proxy.js +45 -0
  75. package/lib/proxy.js.map +1 -0
  76. package/lib/publications.d.ts +86 -0
  77. package/lib/publications.js +223 -0
  78. package/lib/publications.js.map +1 -0
  79. package/lib/replace.d.ts +31 -0
  80. package/lib/replace.js +151 -0
  81. package/lib/replace.js.map +1 -0
  82. package/lib/storage.d.ts +7 -0
  83. package/lib/storage.js +10 -0
  84. package/lib/storage.js.map +1 -0
  85. package/lib/types/alignment.d.ts +18 -0
  86. package/lib/types/alignment.js +13 -0
  87. package/lib/types/alignment.js.map +1 -0
  88. package/lib/types/annotation/abbreviation.d.ts +3 -0
  89. package/lib/types/annotation/abbreviation.js +20 -0
  90. package/lib/types/annotation/abbreviation.js.map +1 -0
  91. package/lib/types/annotation/annotation-type.d.ts +31 -0
  92. package/lib/types/annotation/annotation-type.js +81 -0
  93. package/lib/types/annotation/annotation-type.js.map +1 -0
  94. package/lib/types/annotation/annotation.d.ts +142 -0
  95. package/lib/types/annotation/annotation.js +23 -0
  96. package/lib/types/annotation/annotation.js.map +1 -0
  97. package/lib/types/annotation/audio.d.ts +3 -0
  98. package/lib/types/annotation/audio.js +24 -0
  99. package/lib/types/annotation/audio.js.map +1 -0
  100. package/lib/types/annotation/blockquote.d.ts +3 -0
  101. package/lib/types/annotation/blockquote.js +8 -0
  102. package/lib/types/annotation/blockquote.js.map +1 -0
  103. package/lib/types/annotation/code.d.ts +3 -0
  104. package/lib/types/annotation/code.js +8 -0
  105. package/lib/types/annotation/code.js.map +1 -0
  106. package/lib/types/annotation/deprecated.d.ts +3 -0
  107. package/lib/types/annotation/deprecated.js +8 -0
  108. package/lib/types/annotation/deprecated.js.map +1 -0
  109. package/lib/types/annotation/end-note-link.d.ts +3 -0
  110. package/lib/types/annotation/end-note-link.js +23 -0
  111. package/lib/types/annotation/end-note-link.js.map +1 -0
  112. package/lib/types/annotation/export.d.ts +3 -0
  113. package/{src/lib/types/annotation/export.ts → lib/types/annotation/export.js} +34 -36
  114. package/lib/types/annotation/export.js.map +1 -0
  115. package/lib/types/annotation/glossary-instance.d.ts +3 -0
  116. package/lib/types/annotation/glossary-instance.js +23 -0
  117. package/lib/types/annotation/glossary-instance.js.map +1 -0
  118. package/lib/types/annotation/has-abbreviation.d.ts +3 -0
  119. package/lib/types/annotation/has-abbreviation.js +20 -0
  120. package/lib/types/annotation/has-abbreviation.js.map +1 -0
  121. package/lib/types/annotation/heading.d.ts +3 -0
  122. package/lib/types/annotation/heading.js +26 -0
  123. package/lib/types/annotation/heading.js.map +1 -0
  124. package/lib/types/annotation/image.d.ts +3 -0
  125. package/lib/types/annotation/image.js +20 -0
  126. package/lib/types/annotation/image.js.map +1 -0
  127. package/lib/types/annotation/indent.d.ts +3 -0
  128. package/lib/types/annotation/indent.js +8 -0
  129. package/lib/types/annotation/indent.js.map +1 -0
  130. package/lib/types/annotation/index.js +5 -0
  131. package/lib/types/annotation/index.js.map +1 -0
  132. package/lib/types/annotation/inline-title.d.ts +3 -0
  133. package/lib/types/annotation/inline-title.js +21 -0
  134. package/lib/types/annotation/inline-title.js.map +1 -0
  135. package/lib/types/annotation/internal-link.d.ts +3 -0
  136. package/lib/types/annotation/internal-link.js +62 -0
  137. package/lib/types/annotation/internal-link.js.map +1 -0
  138. package/lib/types/annotation/leading-space.d.ts +3 -0
  139. package/lib/types/annotation/leading-space.js +8 -0
  140. package/lib/types/annotation/leading-space.js.map +1 -0
  141. package/lib/types/annotation/line-group.d.ts +3 -0
  142. package/lib/types/annotation/line-group.js +8 -0
  143. package/lib/types/annotation/line-group.js.map +1 -0
  144. package/lib/types/annotation/line.d.ts +3 -0
  145. package/lib/types/annotation/line.js +8 -0
  146. package/lib/types/annotation/line.js.map +1 -0
  147. package/lib/types/annotation/link.d.ts +3 -0
  148. package/lib/types/annotation/link.js +27 -0
  149. package/lib/types/annotation/link.js.map +1 -0
  150. package/lib/types/annotation/list-item.d.ts +3 -0
  151. package/lib/types/annotation/list-item.js +8 -0
  152. package/lib/types/annotation/list-item.js.map +1 -0
  153. package/lib/types/annotation/list.d.ts +3 -0
  154. package/lib/types/annotation/list.js +31 -0
  155. package/lib/types/annotation/list.js.map +1 -0
  156. package/lib/types/annotation/mantra.d.ts +3 -0
  157. package/lib/types/annotation/mantra.js +21 -0
  158. package/lib/types/annotation/mantra.js.map +1 -0
  159. package/lib/types/annotation/mention.d.ts +3 -0
  160. package/lib/types/annotation/mention.js +50 -0
  161. package/lib/types/annotation/mention.js.map +1 -0
  162. package/lib/types/annotation/paragraph.d.ts +3 -0
  163. package/lib/types/annotation/paragraph.js +8 -0
  164. package/lib/types/annotation/paragraph.js.map +1 -0
  165. package/lib/types/annotation/quote.d.ts +3 -0
  166. package/lib/types/annotation/quote.js +21 -0
  167. package/lib/types/annotation/quote.js.map +1 -0
  168. package/lib/types/annotation/quoted.d.ts +3 -0
  169. package/lib/types/annotation/quoted.js +21 -0
  170. package/lib/types/annotation/quoted.js.map +1 -0
  171. package/lib/types/annotation/reference.d.ts +3 -0
  172. package/lib/types/annotation/reference.js +8 -0
  173. package/lib/types/annotation/reference.js.map +1 -0
  174. package/lib/types/annotation/span.d.ts +3 -0
  175. package/lib/types/annotation/span.js +29 -0
  176. package/lib/types/annotation/span.js.map +1 -0
  177. package/lib/types/annotation/table-body-data.d.ts +3 -0
  178. package/lib/types/annotation/table-body-data.js +8 -0
  179. package/lib/types/annotation/table-body-data.js.map +1 -0
  180. package/lib/types/annotation/table-body-header.d.ts +3 -0
  181. package/lib/types/annotation/table-body-header.js +8 -0
  182. package/lib/types/annotation/table-body-header.js.map +1 -0
  183. package/lib/types/annotation/table-body-row.d.ts +3 -0
  184. package/lib/types/annotation/table-body-row.js +8 -0
  185. package/lib/types/annotation/table-body-row.js.map +1 -0
  186. package/lib/types/annotation/table.d.ts +3 -0
  187. package/lib/types/annotation/table.js +8 -0
  188. package/lib/types/annotation/table.js.map +1 -0
  189. package/lib/types/annotation/trailer.d.ts +3 -0
  190. package/lib/types/annotation/trailer.js +8 -0
  191. package/lib/types/annotation/trailer.js.map +1 -0
  192. package/lib/types/annotation/transform.d.ts +6 -0
  193. package/lib/types/annotation/transform.js +109 -0
  194. package/lib/types/annotation/transform.js.map +1 -0
  195. package/lib/types/annotation/unknown.d.ts +3 -0
  196. package/lib/types/annotation/unknown.js +8 -0
  197. package/lib/types/annotation/unknown.js.map +1 -0
  198. package/lib/types/bibliography.d.ts +41 -0
  199. package/lib/types/bibliography.js +29 -0
  200. package/lib/types/bibliography.js.map +1 -0
  201. package/{src/lib/types/client.ts → lib/types/client.d.ts} +0 -1
  202. package/lib/types/client.js +2 -0
  203. package/lib/types/client.js.map +1 -0
  204. package/{src/lib/types/editor-content.ts → lib/types/editor-content.d.ts} +7 -11
  205. package/lib/types/editor-content.js +2 -0
  206. package/lib/types/editor-content.js.map +1 -0
  207. package/lib/types/folio.d.ts +17 -0
  208. package/lib/types/folio.js +11 -0
  209. package/lib/types/folio.js.map +1 -0
  210. package/lib/types/glossary-page.d.ts +48 -0
  211. package/lib/types/glossary-page.js +21 -0
  212. package/lib/types/glossary-page.js.map +1 -0
  213. package/lib/types/glossary.d.ts +76 -0
  214. package/lib/types/glossary.js +32 -0
  215. package/lib/types/glossary.js.map +1 -0
  216. package/lib/types/imprint.d.ts +78 -0
  217. package/lib/types/imprint.js +78 -0
  218. package/lib/types/imprint.js.map +1 -0
  219. package/lib/types/index.js +20 -0
  220. package/lib/types/index.js.map +1 -0
  221. package/lib/types/language.d.ts +9 -0
  222. package/lib/types/language.js +41 -0
  223. package/lib/types/language.js.map +1 -0
  224. package/lib/types/layout.d.ts +5 -0
  225. package/lib/types/layout.js +23 -0
  226. package/lib/types/layout.js.map +1 -0
  227. package/lib/types/library.d.ts +19 -0
  228. package/lib/types/library.js +8 -0
  229. package/lib/types/library.js.map +1 -0
  230. package/lib/types/passage.d.ts +73 -0
  231. package/lib/types/passage.js +123 -0
  232. package/lib/types/passage.js.map +1 -0
  233. package/lib/types/semver.js +2 -0
  234. package/lib/types/semver.js.map +1 -0
  235. package/lib/types/title.d.ts +21 -0
  236. package/lib/types/title.js +21 -0
  237. package/lib/types/title.js.map +1 -0
  238. package/lib/types/toh.js +2 -0
  239. package/lib/types/toh.js.map +1 -0
  240. package/{src/lib/types/translation.ts → lib/types/translation.d.ts} +5 -7
  241. package/lib/types/translation.js +2 -0
  242. package/lib/types/translation.js.map +1 -0
  243. package/{src/lib/types/user.ts → lib/types/user.d.ts} +2 -11
  244. package/lib/types/user.js +9 -0
  245. package/lib/types/user.js.map +1 -0
  246. package/lib/types/work.d.ts +37 -0
  247. package/lib/types/work.js +12 -0
  248. package/lib/types/work.js.map +1 -0
  249. package/lib/use-bookmark.d.ts +10 -0
  250. package/lib/use-bookmark.js +30 -0
  251. package/lib/use-bookmark.js.map +1 -0
  252. package/package.json +25 -3
  253. package/ssr.js +6 -0
  254. package/ssr.js.map +1 -0
  255. package/.babelrc +0 -12
  256. package/.eslintrc.json +0 -18
  257. package/README.md +0 -9
  258. package/jest.config.ts +0 -10
  259. package/project.json +0 -21
  260. package/src/lib/auth.ts +0 -203
  261. package/src/lib/bibliography.ts +0 -57
  262. package/src/lib/client-browser.ts +0 -12
  263. package/src/lib/client-server.ts +0 -30
  264. package/src/lib/client-ssr.ts +0 -24
  265. package/src/lib/client-token.ts +0 -24
  266. package/src/lib/feedback.ts +0 -71
  267. package/src/lib/folio.ts +0 -57
  268. package/src/lib/glossary/batch.ts +0 -35
  269. package/src/lib/glossary/instance.ts +0 -54
  270. package/src/lib/glossary/landing.ts +0 -50
  271. package/src/lib/glossary/pagination.ts +0 -471
  272. package/src/lib/imprint.ts +0 -42
  273. package/src/lib/library.ts +0 -209
  274. package/src/lib/local-storage.ts +0 -33
  275. package/src/lib/lookup-entity.ts +0 -122
  276. package/src/lib/panel-url.ts +0 -43
  277. package/src/lib/passage/batch.ts +0 -229
  278. package/src/lib/passage/pagination.ts +0 -277
  279. package/src/lib/passage/read.ts +0 -100
  280. package/src/lib/passage/replace-persistence.ts +0 -153
  281. package/src/lib/passage/save.ts +0 -324
  282. package/src/lib/proxy.ts +0 -68
  283. package/src/lib/publications.ts +0 -381
  284. package/src/lib/replace.spec.ts +0 -154
  285. package/src/lib/replace.ts +0 -244
  286. package/src/lib/storage.ts +0 -23
  287. package/src/lib/types/alignment.ts +0 -32
  288. package/src/lib/types/annotation/abbreviation.ts +0 -30
  289. package/src/lib/types/annotation/annotation-type.ts +0 -219
  290. package/src/lib/types/annotation/annotation.ts +0 -244
  291. package/src/lib/types/annotation/audio.ts +0 -33
  292. package/src/lib/types/annotation/blockquote.ts +0 -18
  293. package/src/lib/types/annotation/code.ts +0 -16
  294. package/src/lib/types/annotation/deprecated.ts +0 -18
  295. package/src/lib/types/annotation/end-note-link.ts +0 -35
  296. package/src/lib/types/annotation/glossary-instance.ts +0 -34
  297. package/src/lib/types/annotation/has-abbreviation.ts +0 -30
  298. package/src/lib/types/annotation/heading.ts +0 -37
  299. package/src/lib/types/annotation/image.ts +0 -29
  300. package/src/lib/types/annotation/indent.ts +0 -16
  301. package/src/lib/types/annotation/inline-title.ts +0 -34
  302. package/src/lib/types/annotation/internal-link.ts +0 -86
  303. package/src/lib/types/annotation/leading-space.ts +0 -18
  304. package/src/lib/types/annotation/line-group.ts +0 -18
  305. package/src/lib/types/annotation/line.ts +0 -16
  306. package/src/lib/types/annotation/link.ts +0 -38
  307. package/src/lib/types/annotation/list-item.ts +0 -16
  308. package/src/lib/types/annotation/list.ts +0 -43
  309. package/src/lib/types/annotation/mantra.ts +0 -31
  310. package/src/lib/types/annotation/mention.ts +0 -64
  311. package/src/lib/types/annotation/paragraph.ts +0 -18
  312. package/src/lib/types/annotation/quote.ts +0 -30
  313. package/src/lib/types/annotation/quoted.ts +0 -30
  314. package/src/lib/types/annotation/reference.ts +0 -18
  315. package/src/lib/types/annotation/span.ts +0 -39
  316. package/src/lib/types/annotation/table-body-data.ts +0 -18
  317. package/src/lib/types/annotation/table-body-header.ts +0 -18
  318. package/src/lib/types/annotation/table-body-row.ts +0 -18
  319. package/src/lib/types/annotation/table.ts +0 -16
  320. package/src/lib/types/annotation/trailer.ts +0 -16
  321. package/src/lib/types/annotation/transform.ts +0 -140
  322. package/src/lib/types/annotation/unknown.ts +0 -16
  323. package/src/lib/types/bibliography.ts +0 -86
  324. package/src/lib/types/folio.ts +0 -28
  325. package/src/lib/types/glossary-page.ts +0 -86
  326. package/src/lib/types/glossary.ts +0 -115
  327. package/src/lib/types/imprint.ts +0 -159
  328. package/src/lib/types/language.ts +0 -64
  329. package/src/lib/types/layout.ts +0 -37
  330. package/src/lib/types/library.ts +0 -29
  331. package/src/lib/types/passage.ts +0 -220
  332. package/src/lib/types/title.ts +0 -47
  333. package/src/lib/types/work.ts +0 -38
  334. package/src/lib/use-bookmark.ts +0 -45
  335. package/tsconfig.json +0 -20
  336. package/tsconfig.lib.json +0 -26
  337. package/tsconfig.spec.json +0 -22
  338. /package/{src/index.ts → index.d.ts} +0 -0
  339. /package/{src/lib/glossary/index.ts → lib/glossary/index.d.ts} +0 -0
  340. /package/{src/lib/passage/index.ts → lib/passage/index.d.ts} +0 -0
  341. /package/{src/lib/types/annotation/index.ts → lib/types/annotation/index.d.ts} +0 -0
  342. /package/{src/lib/types/index.ts → lib/types/index.d.ts} +0 -0
  343. /package/{src/lib/types/semver.ts → lib/types/semver.d.ts} +0 -0
  344. /package/{src/lib/types/toh.ts → lib/types/toh.d.ts} +0 -0
  345. /package/{src/ssr.ts → ssr.d.ts} +0 -0
@@ -1,100 +0,0 @@
1
- import {
2
- DataClient,
3
- PassageDTO,
4
- annotationsFromDTO,
5
- passageFromDTO,
6
- } from '../types';
7
-
8
- import { PassageConnectionNode } from './pagination';
9
-
10
- export const getPassage = async ({
11
- client,
12
- uuid,
13
- }: {
14
- client: DataClient;
15
- uuid: string;
16
- }) => {
17
- const { data } = await client
18
- .rpc('get_passage_with_annotations', {
19
- uuid_input: uuid,
20
- })
21
- .single();
22
-
23
- if (!data) {
24
- console.warn(`No passage found for uuid: ${uuid}`);
25
- return undefined;
26
- }
27
-
28
- const dto = data as PassageDTO;
29
- return passageFromDTO(
30
- dto,
31
- annotationsFromDTO(dto?.annotations || [], dto?.content.length || 0),
32
- );
33
- };
34
-
35
- export const getPassageByUuidOrXmlId = async ({
36
- client,
37
- uuid,
38
- xmlId,
39
- }: {
40
- client: DataClient;
41
- uuid?: string;
42
- xmlId?: string;
43
- }): Promise<PassageConnectionNode | null> => {
44
- if (!uuid && !xmlId) {
45
- return null;
46
- }
47
-
48
- let query = client
49
- .from('passages')
50
- .select('uuid, content, label, sort, type, xmlId, toh, work_uuid');
51
-
52
- if (uuid) {
53
- query = query.eq('uuid', uuid);
54
- } else if (xmlId) {
55
- query = query.eq('xmlId', xmlId);
56
- }
57
-
58
- const { data, error } = await query.single();
59
-
60
- if (error) {
61
- console.error(`Error fetching passage ${uuid || xmlId}:`, error);
62
- return null;
63
- }
64
-
65
- if (!data) {
66
- return null;
67
- }
68
-
69
- return {
70
- uuid: data.uuid,
71
- workUuid: data.work_uuid,
72
- content: data.content,
73
- label: data.label,
74
- sort: data.sort,
75
- type: data.type,
76
- toh: data.toh ?? null,
77
- xmlId: data.xmlId ?? null,
78
- };
79
- };
80
-
81
- export const getPassageUuidByXmlId = async ({
82
- client,
83
- xmlId,
84
- }: {
85
- client: DataClient;
86
- xmlId: string;
87
- }) => {
88
- const { data, error } = await client
89
- .from('passages')
90
- .select('uuid, workUuid:work_uuid')
91
- .eq('xmlId', xmlId)
92
- .single();
93
-
94
- if (error) {
95
- console.error(`Error fetching passage uuid for xmlId: ${xmlId}`, error);
96
- return;
97
- }
98
-
99
- return data?.uuid;
100
- };
@@ -1,153 +0,0 @@
1
- import {
2
- ANNOTATIONS_TO_IGNORE,
3
- AnnotationDTO,
4
- DataClient,
5
- Passage,
6
- passagesToDTO,
7
- passagesToRowDTO,
8
- } from '../types';
9
-
10
- export type ReplacePassageRow = {
11
- content: string;
12
- label: string | null;
13
- sort: number;
14
- toh: string | null;
15
- type: string;
16
- uuid: string;
17
- work_uuid: string;
18
- xmlId: string | null;
19
- };
20
-
21
- export const fetchReplaceRows = async ({
22
- client,
23
- targetUuids,
24
- }: {
25
- client: DataClient;
26
- targetUuids: string[];
27
- }) => {
28
- const { data, error } = await client
29
- .from('passages')
30
- .select('uuid, work_uuid, content, label, sort, type, toh, xmlId')
31
- .in('uuid', targetUuids);
32
-
33
- if (error) {
34
- console.error('Error fetching replace targets:', error);
35
- return {
36
- ok: false as const,
37
- error: `Failed to fetch replace targets: ${error.message}`,
38
- };
39
- }
40
-
41
- const rowsByUuid = new Map((data ?? []).map((row) => [row.uuid, row]));
42
- const missingUuids = targetUuids.filter((uuid) => !rowsByUuid.has(uuid));
43
- if (missingUuids.length > 0) {
44
- return {
45
- ok: false as const,
46
- error: `Unknown target UUIDs: ${missingUuids.join(', ')}`,
47
- };
48
- }
49
-
50
- return {
51
- ok: true as const,
52
- orderedRows: targetUuids
53
- .map((uuid) => rowsByUuid.get(uuid))
54
- .filter((row): row is ReplacePassageRow => Boolean(row)),
55
- };
56
- };
57
-
58
- export const fetchReplaceAnnotations = async ({
59
- client,
60
- targetUuids,
61
- }: {
62
- client: DataClient;
63
- targetUuids: string[];
64
- }) => {
65
- const { data, error } = await client
66
- .from('passage_annotations')
67
- .select('uuid, content, end, start, type, passage_uuid, toh')
68
- .in('passage_uuid', targetUuids)
69
- .not('type', 'in', `(${ANNOTATIONS_TO_IGNORE.join(',')})`);
70
-
71
- if (error) {
72
- console.error('Error fetching annotations for replace:', error);
73
- return {
74
- ok: false as const,
75
- error: `Failed to fetch annotations: ${error.message}`,
76
- };
77
- }
78
-
79
- return {
80
- ok: true as const,
81
- rawAnnotations: (data ?? []) as AnnotationDTO[],
82
- };
83
- };
84
-
85
- export const persistReplaceChanges = async ({
86
- client,
87
- rawAnnotations,
88
- updatedPassages,
89
- }: {
90
- client: DataClient;
91
- rawAnnotations: AnnotationDTO[];
92
- updatedPassages: Passage[];
93
- }) => {
94
- const passageRowDtos = passagesToRowDTO(updatedPassages);
95
- const annotationDtos = passagesToDTO(updatedPassages).flatMap(
96
- (passage) => passage.annotations || [],
97
- );
98
- const updatedPassageUuids = updatedPassages.map((passage) => passage.uuid);
99
- const updatedAnnotationUuids = new Set(annotationDtos.map((a) => a.uuid));
100
- const annotationsToDelete = rawAnnotations.filter(
101
- (annotation) =>
102
- updatedPassageUuids.includes(annotation.passage_uuid || '') &&
103
- !updatedAnnotationUuids.has(annotation.uuid),
104
- );
105
-
106
- const { error: passageError } = await client
107
- .from('passages')
108
- .upsert(passageRowDtos, { onConflict: 'uuid' });
109
-
110
- if (passageError) {
111
- console.error('Error saving replaced passages:', passageError);
112
- return {
113
- ok: false as const,
114
- error: `Failed to save replaced passages: ${passageError.message}`,
115
- };
116
- }
117
-
118
- if (annotationDtos.length > 0) {
119
- const { error: annotationError } = await client
120
- .from('passage_annotations')
121
- .upsert(annotationDtos, { onConflict: 'uuid' });
122
-
123
- if (annotationError) {
124
- console.error('Error saving replaced annotations:', annotationError);
125
- return {
126
- ok: false as const,
127
- error: `Failed to save replaced annotations: ${annotationError.message}`,
128
- };
129
- }
130
- }
131
-
132
- if (annotationsToDelete.length > 0) {
133
- const { error: deleteError } = await client
134
- .from('passage_annotations')
135
- .delete()
136
- .in(
137
- 'uuid',
138
- annotationsToDelete.map((annotation) => annotation.uuid),
139
- );
140
-
141
- if (deleteError) {
142
- console.error('Error deleting replaced annotations:', deleteError);
143
- return {
144
- ok: false as const,
145
- error: `Failed to delete replaced annotations: ${deleteError.message}`,
146
- };
147
- }
148
- }
149
-
150
- return {
151
- ok: true as const,
152
- };
153
- };
@@ -1,324 +0,0 @@
1
- import {
2
- ANNOTATIONS_TO_IGNORE,
3
- DataClient,
4
- Passage,
5
- passagesToDTO,
6
- passagesToRowDTO,
7
- } from '../types';
8
-
9
- const SAVE_PAGE_SIZE = 500;
10
-
11
- export const savePassages = async ({
12
- client,
13
- passages,
14
- }: {
15
- client: DataClient;
16
- passages: Passage[];
17
- }) => {
18
- /**
19
- * 1. Extract all annotations from savePassages
20
- * 2. Query the database for all current annotations for the savePassages
21
- * 3. Determine which annotations need to be deleted or upserted
22
- * 4. Upsert the passages
23
- * 5. Upsert the annotations
24
- * 6. Delete the annotations that are no longer present
25
- */
26
- const dtos = passagesToDTO(passages);
27
- const passageRowDtos = passagesToRowDTO(passages);
28
- const passageUuids = passages.map((p) => p.uuid);
29
- const annotations = dtos.flatMap((p) => p.annotations || []);
30
-
31
- const { data: existingAnnotations } = await client
32
- .from('passage_annotations')
33
- .select(`uuid`)
34
- .in('passage_uuid', passageUuids)
35
- .not('type', 'in', `(${ANNOTATIONS_TO_IGNORE.join(',')})`);
36
-
37
- const annotationsToDelete = existingAnnotations?.filter(
38
- (ea) => !annotations.find((a) => a.uuid === ea.uuid),
39
- );
40
-
41
- const { error: passageError } = await client
42
- .from('passages')
43
- .upsert(passageRowDtos, { onConflict: 'uuid' });
44
-
45
- if (passageError) {
46
- console.error('Error saving passages:', passageError);
47
- return;
48
- }
49
-
50
- if (annotations.length > 0) {
51
- const { error: annotationError } = await client
52
- .from('passage_annotations')
53
- .upsert(annotations, { onConflict: 'uuid' });
54
-
55
- if (annotationError) {
56
- console.error('Error saving annotations:', annotationError);
57
- throw annotationError;
58
- }
59
- }
60
-
61
- if (annotationsToDelete && annotationsToDelete.length > 0) {
62
- const { error: deleteError } = await client
63
- .from('passage_annotations')
64
- .delete()
65
- .in(
66
- 'uuid',
67
- annotationsToDelete.map((a) => a.uuid),
68
- );
69
-
70
- if (deleteError) {
71
- console.error('Error deleting annotations:', deleteError);
72
- throw deleteError;
73
- }
74
- }
75
- };
76
-
77
- async function normalizePassageLabelsAfter({
78
- client,
79
- workUuid,
80
- fromSort,
81
- fromLabel,
82
- delta,
83
- }: {
84
- client: DataClient;
85
- workUuid: string;
86
- fromSort: number;
87
- fromLabel: string;
88
- delta: number;
89
- }): Promise<void> {
90
- const parts = fromLabel.split('.');
91
- const depth = parts.length;
92
- const prefix = depth > 1 ? `${parts.slice(0, -1).join('.')}.` : '';
93
- let nextInt = Number.parseInt(parts[depth - 1], 10) + Math.max(delta, 0);
94
- let lastSort = fromSort;
95
- let done = false;
96
-
97
- while (!done) {
98
- const { data, error } = await client
99
- .from('passages')
100
- .select('uuid, label, sort')
101
- .eq('work_uuid', workUuid)
102
- .gt('sort', lastSort)
103
- .order('sort', { ascending: true })
104
- .limit(SAVE_PAGE_SIZE);
105
-
106
- if (error || !data || data.length === 0) break;
107
-
108
- const labelUpdates: { uuid: string; label: string }[] = [];
109
- const prefixRenames: { oldPrefix: string; newPrefix: string }[] = [];
110
-
111
- for (const row of data) {
112
- const rowParts = (row.label ?? '').split('.');
113
-
114
- if (rowParts.length < depth || !row.label?.startsWith(prefix)) {
115
- done = true;
116
- break;
117
- }
118
-
119
- if (rowParts.length > depth) continue;
120
-
121
- const expectedLabel = prefix + nextInt;
122
- if (row.label === expectedLabel) {
123
- done = true;
124
- break;
125
- }
126
-
127
- labelUpdates.push({ uuid: row.uuid, label: expectedLabel });
128
- prefixRenames.push({
129
- oldPrefix: `${row.label}.`,
130
- newPrefix: `${expectedLabel}.`,
131
- });
132
- nextInt++;
133
- }
134
-
135
- if (labelUpdates.length > 0) {
136
- const { error: upsertError } = await client
137
- .from('passages')
138
- .upsert(labelUpdates, { onConflict: 'uuid' });
139
- if (upsertError) {
140
- console.error('Error normalizing passage labels:', upsertError);
141
- }
142
-
143
- for (const { oldPrefix, newPrefix } of prefixRenames) {
144
- const { error: prefixError } = await client.rpc(
145
- 'rename_passage_label_prefix',
146
- {
147
- p_work_uuid: workUuid,
148
- p_old_prefix: oldPrefix,
149
- p_new_prefix: newPrefix,
150
- },
151
- );
152
- if (prefixError) {
153
- console.error('Error renaming passage label prefix:', prefixError);
154
- }
155
- }
156
- }
157
-
158
- if (done || data.length < SAVE_PAGE_SIZE) break;
159
- lastSort = data[data.length - 1].sort;
160
- }
161
- }
162
-
163
- export type SavePassagesWithDeletionsResult = {
164
- success: boolean;
165
- savedCount: number;
166
- deletedCount?: number;
167
- error?: string;
168
- };
169
-
170
- export const savePassagesWithDeletions = async ({
171
- client,
172
- passages,
173
- deletedUuids = [],
174
- }: {
175
- client: DataClient;
176
- passages: Passage[];
177
- deletedUuids?: string[];
178
- }): Promise<SavePassagesWithDeletionsResult> => {
179
- const inputUuids = passages.map((p) => p.uuid);
180
- const { data: existingRows } = await client
181
- .from('passages')
182
- .select('uuid')
183
- .in('uuid', inputUuids);
184
- const existingUuidSet = new Set((existingRows ?? []).map((r) => r.uuid));
185
- const newPassages = passages.filter((p) => !existingUuidSet.has(p.uuid));
186
- const sortedNewPassages = [...newPassages].sort((a, b) => b.sort - a.sort);
187
-
188
- for (const passage of sortedNewPassages) {
189
- const { error } = await client.rpc('shift_passage_sorts', {
190
- p_work_uuid: passage.workUuid,
191
- p_from_sort: passage.sort,
192
- p_delta: 1,
193
- });
194
- if (error) {
195
- console.error('Error shifting passage sorts:', error);
196
- }
197
- }
198
-
199
- for (const passage of sortedNewPassages) {
200
- await normalizePassageLabelsAfter({
201
- client,
202
- workUuid: passage.workUuid,
203
- fromSort: passage.sort,
204
- fromLabel: passage.label,
205
- delta: 1,
206
- });
207
- }
208
-
209
- let deletedCount = 0;
210
- if (deletedUuids.length > 0) {
211
- const { data: deletedPassages } = await client
212
- .from('passages')
213
- .select('uuid, sort, label, work_uuid')
214
- .in('uuid', deletedUuids);
215
-
216
- if (deletedPassages && deletedPassages.length > 0) {
217
- const sortedDeleted = [...deletedPassages].sort(
218
- (a, b) => b.sort - a.sort,
219
- );
220
- for (const deletedPassage of sortedDeleted) {
221
- await normalizePassageLabelsAfter({
222
- client,
223
- workUuid: deletedPassage.work_uuid,
224
- fromSort: deletedPassage.sort,
225
- fromLabel: deletedPassage.label,
226
- delta: -1,
227
- });
228
- }
229
-
230
- const { error: deleteAnnotationsError } = await client
231
- .from('passage_annotations')
232
- .delete()
233
- .in('passage_uuid', deletedUuids);
234
-
235
- if (deleteAnnotationsError) {
236
- console.error(
237
- 'Error deleting annotations for deleted passages:',
238
- deleteAnnotationsError,
239
- );
240
- }
241
-
242
- const { error: deletePassagesError } = await client
243
- .from('passages')
244
- .delete()
245
- .in('uuid', deletedUuids);
246
-
247
- if (deletePassagesError) {
248
- console.error('Error deleting passages:', deletePassagesError);
249
- return {
250
- success: false,
251
- savedCount: 0,
252
- error: `Failed to delete passages: ${deletePassagesError.message}`,
253
- };
254
- }
255
-
256
- deletedCount = deletedPassages.length;
257
- }
258
- }
259
-
260
- const dtos = passagesToDTO(passages);
261
- const passageRowDtos = passagesToRowDTO(passages);
262
- const passageUuids = passages.map((p) => p.uuid);
263
- const annotations = dtos.flatMap((p) => p.annotations || []);
264
- const { data: existingAnnotations } = await client
265
- .from('passage_annotations')
266
- .select('uuid')
267
- .in('passage_uuid', passageUuids)
268
- .not('type', 'in', `(${ANNOTATIONS_TO_IGNORE.join(',')})`);
269
-
270
- const annotationsToDelete = existingAnnotations?.filter(
271
- (existingAnnotation) =>
272
- !annotations.find(
273
- (annotation) => annotation.uuid === existingAnnotation.uuid,
274
- ),
275
- );
276
-
277
- const { error: passageError } = await client
278
- .from('passages')
279
- .upsert(passageRowDtos, { onConflict: 'uuid' });
280
-
281
- if (passageError) {
282
- console.error('Error saving passages:', passageError);
283
- return {
284
- success: false,
285
- savedCount: 0,
286
- error: `Failed to save passages: ${passageError.message}`,
287
- };
288
- }
289
-
290
- if (annotations.length > 0) {
291
- const { error: annotationError } = await client
292
- .from('passage_annotations')
293
- .upsert(annotations, { onConflict: 'uuid' });
294
-
295
- if (annotationError) {
296
- console.error('Error saving annotations:', annotationError);
297
- return {
298
- success: false,
299
- savedCount: passages.length,
300
- error: `Passages saved but annotations failed: ${annotationError.message}`,
301
- };
302
- }
303
- }
304
-
305
- if (annotationsToDelete && annotationsToDelete.length > 0) {
306
- const { error: deleteError } = await client
307
- .from('passage_annotations')
308
- .delete()
309
- .in(
310
- 'uuid',
311
- annotationsToDelete.map((annotation) => annotation.uuid),
312
- );
313
-
314
- if (deleteError) {
315
- console.error('Error deleting annotations:', deleteError);
316
- }
317
- }
318
-
319
- return {
320
- success: true,
321
- savedCount: passages.length,
322
- deletedCount,
323
- };
324
- };
package/src/lib/proxy.ts DELETED
@@ -1,68 +0,0 @@
1
- import { createServerClient } from '@supabase/ssr';
2
- import { jwtDecode } from 'jwt-decode';
3
- import { NextResponse, type NextRequest } from 'next/server';
4
- import { UserRole } from './types';
5
-
6
- export async function updateSession(request: NextRequest) {
7
- const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
8
- const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY;
9
-
10
- if (!supabaseUrl || !supabaseAnonKey) {
11
- throw new Error('Missing Supabase credentials');
12
- }
13
- let supabaseResponse = NextResponse.next({
14
- request,
15
- });
16
-
17
- const supabase = createServerClient(supabaseUrl, supabaseAnonKey, {
18
- cookies: {
19
- getAll() {
20
- return request.cookies.getAll();
21
- },
22
- setAll(
23
- cookiesToSet: Array<{
24
- name: string;
25
- value: string;
26
- options?: Record<string, unknown>;
27
- }>,
28
- ) {
29
- cookiesToSet.forEach(({ name, value }) =>
30
- request.cookies.set(name, value),
31
- );
32
- supabaseResponse = NextResponse.next({
33
- request,
34
- });
35
- cookiesToSet.forEach(({ name, value, options }) =>
36
- supabaseResponse.cookies.set(name, value, options),
37
- );
38
- },
39
- },
40
- });
41
-
42
- // Do not run code between update and
43
- // supabase.auth.getUser(). A simple mistake could make it very hard to debug
44
- // issues with users being randomly logged out.
45
-
46
- // IMPORTANT: DO NOT REMOVE auth.getUser()
47
-
48
- const {
49
- data: { user },
50
- } = await supabase.auth.getUser();
51
-
52
- const {
53
- data: { session },
54
- } = await supabase.auth.getSession();
55
- let role: UserRole = 'reader';
56
- if (session?.access_token) {
57
- try {
58
- const { user_role: userRole } = jwtDecode(session.access_token) as {
59
- user_role: string;
60
- };
61
- role = (userRole as UserRole) || 'reader';
62
- } catch (error) {
63
- console.error('Failed to decode JWT:', error);
64
- }
65
- }
66
-
67
- return { user, role, supabaseResponse };
68
- }