@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
package/.babelrc DELETED
@@ -1,12 +0,0 @@
1
- {
2
- "presets": [
3
- [
4
- "@nx/react/babel",
5
- {
6
- "runtime": "automatic",
7
- "useBuiltIns": "usage"
8
- }
9
- ]
10
- ],
11
- "plugins": []
12
- }
package/.eslintrc.json DELETED
@@ -1,18 +0,0 @@
1
- {
2
- "extends": ["plugin:@nx/react", "../../.eslintrc.json"],
3
- "ignorePatterns": ["!**/*"],
4
- "overrides": [
5
- {
6
- "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
7
- "rules": {}
8
- },
9
- {
10
- "files": ["*.ts", "*.tsx"],
11
- "rules": {}
12
- },
13
- {
14
- "files": ["*.js", "*.jsx"],
15
- "rules": {}
16
- }
17
- ]
18
- }
package/README.md DELETED
@@ -1,9 +0,0 @@
1
- # @eightyfourthousand/data-access
2
-
3
- Shared data-access clients, DTO mappers, and domain types for 84000 applications.
4
-
5
- Use this package for typed access to shared application data models and server/client data helpers.
6
-
7
- ## Running unit tests
8
-
9
- Run `nx test data-access` to execute the unit tests via [Jest](https://jestjs.io).
package/jest.config.ts DELETED
@@ -1,10 +0,0 @@
1
- module.exports = {
2
- displayName: 'data-access',
3
- preset: '../../jest.preset.js',
4
- transform: {
5
- '^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '@nx/react/plugins/jest',
6
- '^.+\\.[tj]sx?$': ['babel-jest', { presets: ['@nx/react/babel'] }],
7
- },
8
- moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
9
- coverageDirectory: '../../coverage/libs/data-access',
10
- };
package/project.json DELETED
@@ -1,21 +0,0 @@
1
- {
2
- "name": "data-access",
3
- "$schema": "../../node_modules/nx/schemas/project-schema.json",
4
- "sourceRoot": "libs/data-access/src",
5
- "projectType": "library",
6
- "tags": [],
7
- "targets": {
8
- "build": {
9
- "executor": "@nx/js:tsc",
10
- "outputs": ["{options.outputPath}"],
11
- "options": {
12
- "outputPath": "dist/libs/data-access",
13
- "main": "libs/data-access/src/index.ts",
14
- "tsConfig": "libs/data-access/tsconfig.lib.json",
15
- "rootDir": "libs/data-access/src",
16
- "generateExportsField": true,
17
- "additionalEntryPoints": ["libs/data-access/src/ssr.ts"]
18
- }
19
- }
20
- }
21
- }
package/src/lib/auth.ts DELETED
@@ -1,203 +0,0 @@
1
- import { jwtDecode } from 'jwt-decode';
2
- import { DataClient, UserClaims, UserPermission, UserRole } from './types';
3
-
4
- export const getSession = async ({ client }: { client: DataClient }) => {
5
- const { data, error } = await client.auth.getSession();
6
- if (error || !data?.session) {
7
- console.info(`Failed to get session data: ${error}`);
8
- return null;
9
- }
10
-
11
- const { access_token } = data.session;
12
- if (!access_token) {
13
- return null;
14
- }
15
-
16
- try {
17
- const decoded = jwtDecode(access_token);
18
- const { user_role: role = 'reader' } = decoded as {
19
- user_role: UserRole;
20
- };
21
- const claims: UserClaims = {
22
- role,
23
- };
24
-
25
- return { claims, ...data.session };
26
- } catch (error) {
27
- console.error('Failed to decode JWT:', error);
28
- return null;
29
- }
30
- };
31
-
32
- export const getUser = async ({ client }: { client: DataClient }) => {
33
- const session = await getSession({ client });
34
- if (!session) {
35
- return null;
36
- }
37
-
38
- const { claims, user } = session;
39
- const { role } = claims;
40
-
41
- const { id, email, user_metadata: metadata } = user;
42
- const { name, picture } = metadata;
43
-
44
- if (!id || !email) {
45
- return null;
46
- }
47
-
48
- const { error, data } = await client
49
- .from('user_profiles')
50
- .select('username, fullName:full_name, avatar:avatar_url, subscriptions')
51
- .eq('id', id)
52
- .single();
53
-
54
- if (error) {
55
- console.warn(`Failed to fetch user profile: ${error.message}`);
56
- }
57
-
58
- const { username, fullName, avatar, subscriptions } = data || {};
59
- const subsArray = Array.isArray(subscriptions) ? subscriptions : [];
60
-
61
- return {
62
- id,
63
- email,
64
- username: username || email,
65
- name: fullName || name,
66
- avatar: avatar || picture,
67
- role,
68
- subscriptions: subsArray,
69
- };
70
- };
71
-
72
- export const hasPermission = async ({
73
- client,
74
- permission,
75
- }: {
76
- client: DataClient;
77
- permission: UserPermission;
78
- }) => {
79
- const { data, error } = await client.rpc('authorize', {
80
- requested_permission: permission,
81
- });
82
- if (error) {
83
- console.error(`Failed to check permission: ${error.message}`);
84
- return false;
85
- }
86
- return data as boolean;
87
- };
88
-
89
- export const loginWithGoogle = async ({
90
- client,
91
- redirectTo = undefined,
92
- }: {
93
- client: DataClient;
94
- redirectTo: string | undefined;
95
- }) => {
96
- await client.auth.signInWithOAuth({
97
- provider: 'google',
98
- options: {
99
- redirectTo,
100
- queryParams: {
101
- access_type: 'offline',
102
- prompt: 'consent',
103
- hd: '84000.co',
104
- },
105
- },
106
- });
107
- };
108
-
109
- export const loginWithApple = async ({
110
- client,
111
- redirectTo = undefined,
112
- }: {
113
- client: DataClient;
114
- redirectTo: string | undefined;
115
- }) => {
116
- await client.auth.signInWithOAuth({
117
- provider: 'apple',
118
- options: {
119
- redirectTo,
120
- queryParams: {
121
- scope: 'email name',
122
- },
123
- },
124
- });
125
- };
126
-
127
- export const loginWithEmail = async ({
128
- client,
129
- email,
130
- password,
131
- }: {
132
- client: DataClient;
133
- email: string;
134
- password: string;
135
- }) => {
136
- const { error } = await client.auth.signInWithPassword({
137
- email,
138
- password,
139
- });
140
-
141
- if (error) {
142
- console.error(`Failed to login with email: ${error.message}`);
143
- throw error;
144
- }
145
- };
146
-
147
- export const logout = async ({ client }: { client: DataClient }) => {
148
- await client.auth.signOut();
149
- };
150
-
151
- export const resetPassword = async ({
152
- client,
153
- email,
154
- redirectTo = undefined,
155
- }: {
156
- client: DataClient;
157
- email: string;
158
- redirectTo?: string;
159
- }) => {
160
- const { error } = await client.auth.resetPasswordForEmail(email, {
161
- redirectTo,
162
- });
163
-
164
- if (error) {
165
- console.error(`Failed to reset password: ${error.message}`);
166
- throw error;
167
- }
168
- };
169
-
170
- export const signUpWithEmail = async ({
171
- client,
172
- email,
173
- password,
174
- redirectTo = undefined,
175
- }: {
176
- client: DataClient;
177
- email: string;
178
- password: string;
179
- redirectTo?: string;
180
- }) => {
181
- const { error } = await client.auth.signUp({
182
- email,
183
- password,
184
- options: {
185
- emailRedirectTo: redirectTo,
186
- },
187
- });
188
-
189
- if (error) {
190
- console.error(`Failed to sign up with email: ${error.message}`);
191
- throw error;
192
- }
193
- };
194
-
195
- export const deleteAccount = async ({ client }: { client: DataClient }) => {
196
- const { error } = await client.rpc('scholar_account_delete');
197
- if (error) {
198
- console.error(`Failed to delete account: ${error.message}`);
199
- throw error;
200
- }
201
-
202
- await logout({ client });
203
- };
@@ -1,57 +0,0 @@
1
- import {
2
- BibliographyEntriesDTO,
3
- bibliographyEntriesFromDTO,
4
- BibliographyEntryItemDTO,
5
- bibliographyEntryItemFromDTO,
6
- DataClient,
7
- } from './types';
8
-
9
- export const getBibliographyEntries = async ({
10
- client,
11
- uuid,
12
- }: {
13
- client: DataClient;
14
- uuid: string;
15
- }) => {
16
- const { data, error } = await client.rpc('show_bibliographies', {
17
- v_work_uuid: uuid,
18
- });
19
- if (error) {
20
- console.error(
21
- `Error fetching glossary instances for work: ${uuid} `,
22
- error,
23
- );
24
- return [];
25
- }
26
-
27
- const dto = data as BibliographyEntriesDTO;
28
- return bibliographyEntriesFromDTO(dto);
29
- };
30
-
31
- export const getBibliographyEntry = async ({
32
- client,
33
- uuid,
34
- }: {
35
- client: DataClient;
36
- uuid: string;
37
- }) => {
38
- const { data, error } = await client
39
- .from('bibliographies')
40
- .select(
41
- `
42
- uuid::uuid,
43
- work_uuid::uuid,
44
- bibl_html::text
45
- `,
46
- )
47
- .eq('uuid', uuid)
48
- .single();
49
- if (error) {
50
- console.error(`Error fetching bibliography entry: ${uuid} `, error);
51
- return null;
52
- }
53
-
54
- const dto = data as BibliographyEntryItemDTO;
55
-
56
- return bibliographyEntryItemFromDTO(dto);
57
- };
@@ -1,12 +0,0 @@
1
- import { createBrowserClient as createSupabaseClient } from '@supabase/ssr';
2
-
3
- export const createBrowserClient = () => {
4
- const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
5
- const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY;
6
-
7
- if (!supabaseUrl || !supabaseAnonKey) {
8
- throw new Error('Missing Supabase credentials');
9
- }
10
-
11
- return createSupabaseClient(supabaseUrl, supabaseAnonKey);
12
- };
@@ -1,30 +0,0 @@
1
- import {
2
- CookieMethodsServer,
3
- createServerClient as createSupabaseClient,
4
- } from '@supabase/ssr';
5
-
6
- export const createServerClient = ({
7
- cookies,
8
- }: {
9
- cookies: CookieMethodsServer;
10
- }) => {
11
- const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
12
- const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY;
13
-
14
- if (!supabaseUrl || !supabaseAnonKey) {
15
- throw new Error('Missing Supabase credentials');
16
- }
17
-
18
- const client = createSupabaseClient(supabaseUrl, supabaseAnonKey, {
19
- cookies,
20
- });
21
-
22
- // NOTE: we suppress the warning about getSession being called. But is is
23
- // import not to rely on this method for authorization. Rather, it is
24
- // convenient for early exists in server components.
25
- //
26
- // @ts-expect-error - suppressGetSessionWarning is protected
27
- client.auth.suppressGetSessionWarning = true;
28
-
29
- return client;
30
- };
@@ -1,24 +0,0 @@
1
- import { createServerClient as createSupabaseClient } from './client-server';
2
- import { cookies } from 'next/headers';
3
-
4
- export const createServerClient = async () => {
5
- const cookieStore = await cookies();
6
- return createSupabaseClient({
7
- cookies: {
8
- getAll: () => {
9
- return cookieStore.getAll();
10
- },
11
- setAll: (cookiesToSet) => {
12
- try {
13
- cookiesToSet.forEach(({ name, value, options }) =>
14
- cookieStore.set(name, value, options),
15
- );
16
- } catch {
17
- // The `setAll` method was called from a Server Component.
18
- // This can be ignored if you have middleware refreshing
19
- // user sessions.
20
- }
21
- },
22
- },
23
- });
24
- };
@@ -1,24 +0,0 @@
1
- import { createClient } from '@supabase/supabase-js';
2
- import type { DataClient } from './types/client';
3
-
4
- /**
5
- * Create a Supabase client using an access token for authentication.
6
- * Use this for API routes that receive tokens via Authorization header
7
- * instead of cookies (e.g., cross-domain requests).
8
- */
9
- export const createTokenClient = (accessToken: string): DataClient => {
10
- const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
11
- const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY;
12
-
13
- if (!supabaseUrl || !supabaseAnonKey) {
14
- throw new Error('Missing Supabase credentials');
15
- }
16
-
17
- return createClient(supabaseUrl, supabaseAnonKey, {
18
- global: {
19
- headers: {
20
- Authorization: `Bearer ${accessToken}`,
21
- },
22
- },
23
- });
24
- };
@@ -1,71 +0,0 @@
1
- import { parseToh } from '@eightyfourthousand/lib-utils';
2
- import { NextRequest, NextResponse } from 'next/server';
3
- import { Resend } from 'resend';
4
-
5
- async function sendRevisionEmail({
6
- toh,
7
- type,
8
- label,
9
- body,
10
- }: {
11
- toh: string;
12
- type: string;
13
- label: string;
14
- body: string;
15
- }) {
16
- const apiKey = process.env['RESEND_API_KEY'];
17
- const from = process.env['FEEDBACK_SENDER'];
18
- const to = process.env['FEEDBACK_RECIPIENT'];
19
-
20
- if (!apiKey || !from || !to) {
21
- throw new Error('Missing email configuration environment variables');
22
- }
23
-
24
- const resend = new Resend(apiKey);
25
- const trimmedLabel = label.split('\n').join(', ').trim();
26
-
27
- const subject = `[Revision Suggestion] ${parseToh(toh)} - ${type} ${trimmedLabel}`;
28
-
29
- const { error } = await resend.emails.send({
30
- from,
31
- to,
32
- subject,
33
- text: body,
34
- });
35
-
36
- if (error) {
37
- throw new Error(error.message);
38
- }
39
- }
40
-
41
- export async function handleFeedbackPost(request: NextRequest) {
42
- try {
43
- const { toh, type, label, body } = await request.json();
44
-
45
- if (
46
- typeof toh !== 'string' ||
47
- !toh.trim() ||
48
- typeof type !== 'string' ||
49
- !type.trim() ||
50
- typeof label !== 'string' ||
51
- !label.trim() ||
52
- typeof body !== 'string' ||
53
- !body.trim()
54
- ) {
55
- return NextResponse.json(
56
- { error: 'All fields (toh, type, label, body) are required.' },
57
- { status: 400 },
58
- );
59
- }
60
-
61
- await sendRevisionEmail({ toh, type, label, body });
62
-
63
- return NextResponse.json({ success: true });
64
- } catch (error) {
65
- console.error('Failed to send revision email:', error);
66
- return NextResponse.json(
67
- { error: 'Failed to send feedback.' },
68
- { status: 500 },
69
- );
70
- }
71
- }
package/src/lib/folio.ts DELETED
@@ -1,57 +0,0 @@
1
- 'use server';
2
-
3
- import { createServerClient } from './client-ssr';
4
- import { DataClient, TohokuCatalogEntry } from './types';
5
- import { FolioDTO, folioFromDTO } from './types/folio';
6
-
7
- type GetWorkFoliosArgs = {
8
- client: DataClient;
9
- uuid: string;
10
- toh: TohokuCatalogEntry;
11
- page?: number;
12
- size?: number;
13
- };
14
-
15
- export const getWorkFolios = async ({
16
- client,
17
- uuid,
18
- toh,
19
- page = 0,
20
- size = 10,
21
- }: GetWorkFoliosArgs) => {
22
- const start = page * size;
23
- const end = start + size - 1;
24
- const { data, error } = await client
25
- .from('tibetan_works_folios')
26
- .select(
27
- `
28
- folio_uuid,
29
- content::text,
30
- volume_number::int4,
31
- folio_number::int4,
32
- side::text`,
33
- )
34
- .eq('work_uuid', uuid)
35
- .eq('toh', toh)
36
- .order('volume_number', { ascending: true })
37
- .order('folio_number', { ascending: true })
38
- .order('side', { ascending: true })
39
- .range(start, end);
40
-
41
- if (error) {
42
- console.error('Error fetching folios:', error);
43
- return [];
44
- }
45
-
46
- return data.map((dto) => folioFromDTO(dto as FolioDTO));
47
- };
48
-
49
- export const getFolios = async ({
50
- uuid,
51
- toh,
52
- page = 0,
53
- size = 10,
54
- }: Omit<GetWorkFoliosArgs, 'client'>) => {
55
- const client = await createServerClient();
56
- return getWorkFolios({ client, uuid, toh, page, size });
57
- };
@@ -1,35 +0,0 @@
1
- import { DataClient } from '../types';
2
-
3
- export const getGlossaryDisplayNamesByUuids = async ({
4
- client,
5
- glossaryUuids,
6
- }: {
7
- client: DataClient;
8
- glossaryUuids: readonly string[];
9
- }): Promise<Map<string, string>> => {
10
- const namesByUuid = new Map<string, string>();
11
- if (glossaryUuids.length === 0) return namesByUuid;
12
-
13
- const { data, error } = await client
14
- .from('glossaries')
15
- .select('uuid, names:names!name_uuid(content)')
16
- .in('uuid', glossaryUuids as string[]);
17
-
18
- if (error) {
19
- console.error('Error batch loading glossary names:', error);
20
- return namesByUuid;
21
- }
22
-
23
- for (const glossary of data ?? []) {
24
- const names = glossary.names as unknown as
25
- | { content: string }
26
- | { content: string }[]
27
- | null;
28
- const content = Array.isArray(names) ? names[0]?.content : names?.content;
29
- if (content) {
30
- namesByUuid.set(glossary.uuid, content);
31
- }
32
- }
33
-
34
- return namesByUuid;
35
- };
@@ -1,54 +0,0 @@
1
- import {
2
- DataClient,
3
- GlossaryTermInstanceDTO,
4
- GlossaryTermInstancesDTO,
5
- glossaryTermInstanceFromDTO,
6
- } from '../types';
7
-
8
- export const getGlossaryInstances = async ({
9
- client,
10
- uuid,
11
- withAttestations = false,
12
- }: {
13
- client: DataClient;
14
- uuid: string;
15
- withAttestations?: boolean;
16
- }) => {
17
- const { data, error } = await client.rpc('show_glossary_entries', {
18
- v_work_uuid: uuid,
19
- v_with_attestation: withAttestations,
20
- });
21
- if (error) {
22
- console.error(
23
- `Error fetching glossary instances for work: ${uuid} `,
24
- error,
25
- );
26
- return [];
27
- }
28
-
29
- const dto = data as GlossaryTermInstancesDTO;
30
- return dto.glossary_entries.map(glossaryTermInstanceFromDTO).sort((a, b) => {
31
- const nameA = a.names.english || '';
32
- const nameB = b.names.english || '';
33
- return nameA.localeCompare(nameB);
34
- });
35
- };
36
-
37
- export const getGlossaryInstance = async ({
38
- client,
39
- uuid,
40
- }: {
41
- client: DataClient;
42
- uuid: string;
43
- }) => {
44
- const { data, error } = await client.rpc('show_glossary_entry', {
45
- v_glossary_uuid: uuid,
46
- });
47
-
48
- if (error) {
49
- console.error(`Error fetching glossary instance: ${uuid} `, error);
50
- return undefined;
51
- }
52
-
53
- return glossaryTermInstanceFromDTO(data as GlossaryTermInstanceDTO);
54
- };
@@ -1,50 +0,0 @@
1
- import {
2
- DataClient,
3
- GlossaryLandingItem,
4
- GlossaryLandingItemDTO,
5
- glossaryLandingItemFromDTO,
6
- } from '../types';
7
-
8
- export const getAllGlossaryTerms = async ({
9
- client,
10
- uuids,
11
- }: {
12
- client: DataClient;
13
- uuids?: string[];
14
- }): Promise<GlossaryLandingItem[]> => {
15
- const pageSize = 1000;
16
- let start = 0;
17
- let end = pageSize - 1;
18
- let count = pageSize;
19
- const terms: GlossaryLandingItem[] = [];
20
-
21
- while (count === pageSize) {
22
- let rpc = client.rpc('scholar_glossary_get_all');
23
-
24
- if (uuids?.length) {
25
- rpc = rpc.in('authority_uuid', uuids);
26
- }
27
-
28
- const { data, error } = await rpc.range(start, end);
29
-
30
- if (error) {
31
- console.error('Error fetching glossary terms:', error);
32
- return [];
33
- }
34
- if (!data || !data.length) {
35
- break;
36
- }
37
-
38
- const dtos = data as GlossaryLandingItemDTO[];
39
- const items = dtos
40
- .map((item) => glossaryLandingItemFromDTO(item as GlossaryLandingItemDTO))
41
- .flatMap((item) => (item ? [item] : []));
42
-
43
- terms.push(...items);
44
- start += pageSize;
45
- end += pageSize;
46
- count = data.length;
47
- }
48
-
49
- return terms;
50
- };