erudit 4.0.0-dev.3 → 4.0.0-dev.5

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 (336) hide show
  1. package/.nuxtrc +1 -1
  2. package/app/app.vue +34 -34
  3. package/app/components/EruditLink.ts +7 -7
  4. package/app/components/FancyBold.vue +16 -16
  5. package/app/components/FancyCard.vue +52 -58
  6. package/app/components/FancyCardTag.vue +16 -16
  7. package/app/components/Loading.vue +7 -0
  8. package/app/components/Prose.vue +55 -51
  9. package/app/components/ScrollHolder.vue +13 -13
  10. package/app/components/SmartMedia.vue +107 -112
  11. package/app/components/ads/Ads.vue +17 -17
  12. package/app/components/ads/AdsBannerAside.vue +29 -29
  13. package/app/components/ads/AdsBannerBottom.vue +6 -6
  14. package/app/components/ads/AdsReplacer.vue +19 -21
  15. package/app/components/ads/provider/Custom.vue +9 -9
  16. package/app/components/ads/provider/Yandex.vue +56 -56
  17. package/app/components/aside/AsideListItem.vue +47 -52
  18. package/app/components/aside/AsideMajor.vue +6 -6
  19. package/app/components/aside/AsideMinor.vue +47 -55
  20. package/app/components/aside/AsidePlainMessage.vue +9 -9
  21. package/app/components/aside/AsideSwitch.vue +53 -54
  22. package/app/components/aside/major/PaneHolder.vue +61 -61
  23. package/app/components/aside/major/PaneSwitcher.vue +50 -55
  24. package/app/components/aside/major/PaneSwitcherButton.vue +24 -24
  25. package/app/components/aside/major/PaneTemplate.vue +3 -3
  26. package/app/components/aside/major/SiteInfo.vue +40 -42
  27. package/app/components/aside/major/contentNav/PaneBookNav.vue +107 -116
  28. package/app/components/aside/major/contentNav/PaneGlobalNav.vue +19 -19
  29. package/app/components/aside/major/contentNav/items/ContentNavBook.vue +8 -8
  30. package/app/components/aside/major/contentNav/items/ContentNavFolder.vue +55 -56
  31. package/app/components/aside/major/contentNav/items/ContentNavItem.vue +16 -16
  32. package/app/components/aside/major/contentNav/items/ContentNavPage.vue +2 -6
  33. package/app/components/aside/major/contentNav/items/ContentNavSeparator.vue +34 -35
  34. package/app/components/aside/major/contentNav/items/ContentNavTopic.vue +6 -6
  35. package/app/components/aside/major/contentNav/items/Flags.vue +31 -33
  36. package/app/components/aside/major/contentNav/items/ItemTemplate.vue +13 -13
  37. package/app/components/aside/major/languages/PaneLanguages.vue +40 -40
  38. package/app/components/aside/major/pages/PanePages.vue +45 -45
  39. package/app/components/aside/major/search/PaneSearch.vue +111 -100
  40. package/app/components/aside/major/search/SearchInput.vue +52 -53
  41. package/app/components/aside/major/search/SearchResult.vue +125 -74
  42. package/app/components/aside/major/search/SearchStatus.vue +28 -28
  43. package/app/components/aside/major/search/search.worker.ts +129 -129
  44. package/app/components/aside/major/settings/BuildTime.vue +15 -15
  45. package/app/components/aside/major/settings/EngineVersion.vue +8 -7
  46. package/app/components/aside/major/settings/PaneSettings.vue +8 -8
  47. package/app/components/aside/major/settings/ThemeSwitcher.vue +38 -36
  48. package/app/components/aside/major/settings/repository/Repository.vue +18 -18
  49. package/app/components/aside/major/settings/repository/SecondaryGitHub.vue +47 -47
  50. package/app/components/aside/minor/AsideMinorPane.vue +5 -5
  51. package/app/components/aside/minor/AsideMinorPlainHeader.vue +20 -20
  52. package/app/components/aside/minor/content/AsideMinorContentContributions.vue +47 -51
  53. package/app/components/aside/minor/content/AsideMinorContentPage.vue +37 -37
  54. package/app/components/aside/minor/content/AsideMinorContentTopic.vue +61 -66
  55. package/app/components/aside/minor/content/ButtonPaneContributions.vue +101 -114
  56. package/app/components/aside/minor/content/ButtonPaneImprove.vue +112 -120
  57. package/app/components/aside/minor/content/Contribution.vue +36 -36
  58. package/app/components/aside/minor/content/Toc.vue +163 -163
  59. package/app/components/aside/minor/content/TocItem.vue +91 -91
  60. package/app/components/aside/minor/content/TopicPartButton.vue +35 -35
  61. package/app/components/aside/minor/contributor/AsideMinorContributor.vue +36 -39
  62. package/app/components/aside/minor/contributor/ItemBook.vue +33 -39
  63. package/app/components/aside/minor/contributor/ItemContent.vue +17 -17
  64. package/app/components/aside/minor/news/AsideMinorNews.vue +132 -132
  65. package/app/components/aside/minor/news/NewsItem.vue +69 -69
  66. package/app/components/aside/minor/news/RenderNewsElement.vue +42 -42
  67. package/app/components/aside/minor/news/elements/Mix.vue +11 -11
  68. package/app/components/aside/minor/news/elements/P.vue +14 -14
  69. package/app/components/aside/minor/news/elements/Ref.vue +59 -58
  70. package/app/components/aside/minor/news/elements/Text.vue +18 -18
  71. package/app/components/indexPage/IndexPagePersons.vue +116 -117
  72. package/app/components/main/MainAction.vue +26 -20
  73. package/app/components/main/MainBreadcrumbs.vue +28 -28
  74. package/app/components/main/MainContentChild.vue +44 -47
  75. package/app/components/main/MainContentChildren.vue +13 -14
  76. package/app/components/main/MainDecoration.vue +15 -15
  77. package/app/components/main/MainDescription.vue +13 -13
  78. package/app/components/main/MainFlag.vue +129 -133
  79. package/app/components/main/MainFlags.vue +17 -17
  80. package/app/components/main/MainGlow.vue +12 -12
  81. package/app/components/main/MainQuickLink.vue +90 -91
  82. package/app/components/main/MainQuickLinks.vue +40 -40
  83. package/app/components/main/MainQuote.vue +149 -159
  84. package/app/components/main/MainQuoteLoader.vue +86 -86
  85. package/app/components/main/MainSection.vue +44 -44
  86. package/app/components/main/MainSectionPreamble.vue +5 -5
  87. package/app/components/main/MainSubTitle.vue +11 -12
  88. package/app/components/main/MainTitle.vue +32 -32
  89. package/app/components/main/MainTopicPartPage.vue +88 -88
  90. package/app/components/main/MainTopicPartSwitch.vue +67 -71
  91. package/app/components/main/connections/Deps.vue +30 -34
  92. package/app/components/main/connections/Externals.vue +80 -104
  93. package/app/components/main/connections/MainConnections.vue +90 -94
  94. package/app/components/main/connections/MainConnectionsButton.vue +81 -81
  95. package/app/components/main/connections/ScrollPane.vue +10 -10
  96. package/app/components/main/contentStats/Item.vue +28 -34
  97. package/app/components/main/contentStats/ItemElement.vue +19 -19
  98. package/app/components/main/contentStats/ItemMaterials.vue +11 -11
  99. package/app/components/main/contentStats/MainContentStats.vue +50 -53
  100. package/app/components/preview/Preview.vue +110 -121
  101. package/app/components/preview/PreviewError.vue +4 -4
  102. package/app/components/preview/PreviewLoading.vue +3 -3
  103. package/app/components/preview/PreviewScreen.vue +48 -48
  104. package/app/components/preview/PreviewScreenButton.vue +27 -27
  105. package/app/components/preview/screen/ContentPage.vue +27 -30
  106. package/app/components/preview/screen/DirectLink.vue +13 -13
  107. package/app/components/preview/screen/Unique.vue +31 -32
  108. package/app/components/site/SiteAside.vue +50 -51
  109. package/app/components/site/SiteAsideOverlay.vue +8 -8
  110. package/app/components/site/SiteMain.vue +11 -11
  111. package/app/components/transition/Fade.vue +16 -16
  112. package/app/components/transition/Slide.vue +27 -27
  113. package/app/components/tree/TreeContainer.vue +3 -3
  114. package/app/components/tree/TreeItem.vue +27 -31
  115. package/app/composables/ads.ts +11 -11
  116. package/app/composables/analytics.ts +102 -102
  117. package/app/composables/appElements.ts +21 -21
  118. package/app/composables/aside.ts +15 -15
  119. package/app/composables/asideMajorPane.ts +82 -82
  120. package/app/composables/asideMinor.ts +109 -109
  121. package/app/composables/contentNav.ts +7 -7
  122. package/app/composables/favicon.ts +103 -108
  123. package/app/composables/file.ts +4 -3
  124. package/app/composables/formatText.ts +100 -100
  125. package/app/composables/loading.ts +26 -2
  126. package/app/composables/mainContent.ts +22 -22
  127. package/app/composables/og.ts +184 -182
  128. package/app/composables/phrases.ts +98 -98
  129. package/app/composables/preview.ts +44 -44
  130. package/app/composables/route.ts +4 -2
  131. package/app/composables/theme.ts +47 -51
  132. package/app/composables/url.ts +19 -11
  133. package/app/formatters/ru.ts +14 -14
  134. package/app/pages/article/[...articleId].vue +12 -12
  135. package/app/pages/book/[...bookId].vue +56 -56
  136. package/app/pages/contributor/[contributorId].vue +144 -150
  137. package/app/pages/contributors.vue +95 -99
  138. package/app/pages/group/[...groupId].vue +58 -58
  139. package/app/pages/index.vue +113 -117
  140. package/app/pages/page/[...pageId].vue +60 -60
  141. package/app/pages/practice/[...practiceId].vue +12 -12
  142. package/app/pages/sponsors.vue +88 -91
  143. package/app/pages/summary/[...summaryId].vue +12 -12
  144. package/app/plugins/appSetup/client/htmlBranding.ts +6 -6
  145. package/app/plugins/appSetup/client/welcome.ts +37 -35
  146. package/app/plugins/appSetup/config.ts +6 -6
  147. package/app/plugins/appSetup/global.ts +3 -3
  148. package/app/plugins/appSetup/index.ts +27 -28
  149. package/app/plugins/prerender.server.ts +40 -40
  150. package/app/router.options.ts +5 -5
  151. package/app/scripts/theme.js +21 -24
  152. package/app/styles/main.css +128 -124
  153. package/bin/erudit.js +12 -0
  154. package/modules/erudit/env.ts +8 -0
  155. package/modules/erudit/globals/content.ts +4 -4
  156. package/modules/erudit/globals/contributor.ts +1 -1
  157. package/modules/erudit/globals/eruditConfig.ts +5 -10
  158. package/modules/erudit/globals/problem.ts +1 -1
  159. package/modules/erudit/globals/prose.ts +1 -1
  160. package/modules/erudit/globals/public.ts +18 -18
  161. package/modules/erudit/index.ts +50 -60
  162. package/modules/erudit/logger.ts +10 -10
  163. package/modules/erudit/setup/elements/appTemplate.ts +44 -45
  164. package/modules/erudit/setup/elements/globalTemplate.ts +82 -82
  165. package/modules/erudit/setup/elements/globalTypes.ts +259 -273
  166. package/modules/erudit/setup/elements/setup.ts +163 -167
  167. package/modules/erudit/setup/elements/shared.ts +10 -10
  168. package/modules/erudit/setup/elements/tagsTable.ts +28 -28
  169. package/modules/erudit/setup/fullRestart.ts +61 -71
  170. package/modules/erudit/setup/globals.ts +206 -196
  171. package/modules/erudit/setup/publicAssets.ts +43 -52
  172. package/modules/erudit/setup/runtimeConfig.ts +106 -58
  173. package/modules/erudit/watcher.ts +20 -27
  174. package/nuxt.config.ts +102 -84
  175. package/package.json +51 -55
  176. package/server/api/aside/major/frontNav/book/[...shortId].ts +10 -10
  177. package/server/api/aside/major/frontNav/global.ts +5 -5
  178. package/server/api/aside/major/pages.ts +6 -6
  179. package/server/api/contributor/list.ts +60 -61
  180. package/server/api/contributor/page/[contributorId].ts +68 -68
  181. package/server/api/indexPage.ts +81 -81
  182. package/server/api/language/functions.ts +11 -11
  183. package/server/api/language/phrase/[phraseKey].ts +35 -35
  184. package/server/api/main/content/[...contentTypePath].ts +149 -153
  185. package/server/api/news/batch/[batchIndex].ts +5 -5
  186. package/server/api/pageSponsors.ts +56 -58
  187. package/server/api/prerender/content.ts +79 -82
  188. package/server/api/prerender/default.ts +35 -35
  189. package/server/api/prerender/files.ts +10 -10
  190. package/server/api/prerender/frontNav.ts +13 -13
  191. package/server/api/prerender/language.ts +7 -7
  192. package/server/api/prerender/news.ts +8 -8
  193. package/server/api/prerender/quotes.ts +15 -15
  194. package/server/api/preview/contentPage/[...contentTypePath].ts +63 -63
  195. package/server/api/preview/contentUnique/[...contentTypePathUnique].ts +73 -81
  196. package/server/api/problemScript/[...problemScriptPath].ts +88 -92
  197. package/server/api/quote/data/[quoteId].ts +84 -87
  198. package/server/api/quote/ids.ts +3 -3
  199. package/server/erudit/build.ts +132 -137
  200. package/server/erudit/cameos/build.ts +161 -161
  201. package/server/erudit/config.ts +13 -13
  202. package/server/erudit/content/global/build.ts +300 -297
  203. package/server/erudit/content/global/singleton.ts +5 -5
  204. package/server/erudit/content/nav/build.ts +459 -463
  205. package/server/erudit/content/nav/front.ts +125 -127
  206. package/server/erudit/content/nav/repository/books.ts +37 -40
  207. package/server/erudit/content/nav/repository/get.ts +33 -33
  208. package/server/erudit/content/nav/repository/hasChildren.ts +5 -5
  209. package/server/erudit/content/nav/repository/hasNav.ts +3 -3
  210. package/server/erudit/content/nav/repository/hasParent.ts +5 -5
  211. package/server/erudit/content/nav/repository/id.ts +9 -9
  212. package/server/erudit/content/nav/repository/index.ts +9 -9
  213. package/server/erudit/content/nav/repository/order.ts +14 -14
  214. package/server/erudit/content/nav/repository/previousNext.ts +35 -35
  215. package/server/erudit/content/nav/repository/walk.ts +127 -127
  216. package/server/erudit/content/nav/setup.ts +13 -13
  217. package/server/erudit/content/nav/types.ts +24 -24
  218. package/server/erudit/content/repository/breadcrumbs.ts +24 -24
  219. package/server/erudit/content/repository/children.ts +47 -47
  220. package/server/erudit/content/repository/connections.ts +35 -35
  221. package/server/erudit/content/repository/contentLink.ts +16 -16
  222. package/server/erudit/content/repository/decoration.ts +23 -23
  223. package/server/erudit/content/repository/deps.ts +121 -84
  224. package/server/erudit/content/repository/description.ts +11 -11
  225. package/server/erudit/content/repository/elementSnippets.ts +105 -105
  226. package/server/erudit/content/repository/externals.ts +50 -50
  227. package/server/erudit/content/repository/flags.ts +33 -33
  228. package/server/erudit/content/repository/seo.ts +12 -12
  229. package/server/erudit/content/repository/stats.ts +97 -97
  230. package/server/erudit/content/repository/title.ts +27 -27
  231. package/server/erudit/content/repository/topicParts.ts +39 -39
  232. package/server/erudit/content/repository/unique.ts +76 -76
  233. package/server/erudit/content/resolve/book.ts +29 -32
  234. package/server/erudit/content/resolve/group.ts +34 -39
  235. package/server/erudit/content/resolve/index.ts +272 -290
  236. package/server/erudit/content/resolve/page.ts +80 -87
  237. package/server/erudit/content/resolve/topic.ts +220 -246
  238. package/server/erudit/content/resolve/utils/contentError.ts +10 -10
  239. package/server/erudit/content/resolve/utils/insertContentItem.ts +113 -122
  240. package/server/erudit/content/resolve/utils/insertContentResolved.ts +126 -132
  241. package/server/erudit/content/search.ts +146 -163
  242. package/server/erudit/contributors/build.ts +158 -166
  243. package/server/erudit/contributors/global.ts +3 -3
  244. package/server/erudit/contributors/repository/avatarUrl.ts +10 -10
  245. package/server/erudit/contributors/repository/contributions.ts +171 -178
  246. package/server/erudit/contributors/repository/count.ts +3 -3
  247. package/server/erudit/contributors/search.ts +34 -34
  248. package/server/erudit/db/repository/pushFile.ts +23 -26
  249. package/server/erudit/db/repository/pushProblemScript.ts +19 -19
  250. package/server/erudit/db/repository/pushProseLink.ts +40 -40
  251. package/server/erudit/db/schema/cameos.ts +7 -7
  252. package/server/erudit/db/schema/content.ts +18 -18
  253. package/server/erudit/db/schema/contentContributions.ts +15 -15
  254. package/server/erudit/db/schema/contentDeps.ts +21 -21
  255. package/server/erudit/db/schema/contentElementStats.ts +20 -20
  256. package/server/erudit/db/schema/contentProseLinks.ts +23 -23
  257. package/server/erudit/db/schema/contentSnippets.ts +15 -15
  258. package/server/erudit/db/schema/contentToc.ts +16 -16
  259. package/server/erudit/db/schema/contentUniques.ts +19 -25
  260. package/server/erudit/db/schema/contributors.ts +12 -12
  261. package/server/erudit/db/schema/files.ts +11 -11
  262. package/server/erudit/db/schema/groups.ts +6 -6
  263. package/server/erudit/db/schema/index.ts +17 -17
  264. package/server/erudit/db/schema/news.ts +7 -7
  265. package/server/erudit/db/schema/pages.ts +7 -7
  266. package/server/erudit/db/schema/problemScripts.ts +14 -14
  267. package/server/erudit/db/schema/sponsors.ts +9 -9
  268. package/server/erudit/db/schema/topics.ts +9 -9
  269. package/server/erudit/db/setup.ts +62 -62
  270. package/server/erudit/db/types.ts +10 -10
  271. package/server/erudit/global.ts +38 -33
  272. package/server/erudit/importer.ts +94 -97
  273. package/server/erudit/index.ts +96 -90
  274. package/server/erudit/language/list/en.ts +116 -116
  275. package/server/erudit/language/list/ru.ts +120 -120
  276. package/server/erudit/language/list.ts +6 -6
  277. package/server/erudit/language/setup.ts +36 -36
  278. package/server/erudit/language/types.ts +16 -16
  279. package/server/erudit/logger.ts +73 -77
  280. package/server/erudit/news/build.ts +112 -114
  281. package/server/erudit/news/repository/batch.ts +61 -61
  282. package/server/erudit/path.ts +19 -0
  283. package/server/erudit/prose/repository/finalize.ts +68 -68
  284. package/server/erudit/prose/repository/get.ts +54 -54
  285. package/server/erudit/prose/repository/resolve.ts +17 -17
  286. package/server/erudit/prose/storage/callout.ts +16 -14
  287. package/server/erudit/prose/storage/image.ts +22 -20
  288. package/server/erudit/prose/storage/link.ts +222 -226
  289. package/server/erudit/prose/storage/problemScript.ts +23 -21
  290. package/server/erudit/prose/storage/video.ts +16 -14
  291. package/server/erudit/prose/transform/bundleProblemScript.ts +6 -6
  292. package/server/erudit/prose/transform/extensions.ts +15 -15
  293. package/server/erudit/quote/repository/ids.ts +31 -31
  294. package/server/erudit/repository.ts +96 -96
  295. package/server/erudit/sponsors/build.ts +161 -165
  296. package/server/erudit/sponsors/repository/avatarUrl.ts +10 -10
  297. package/server/erudit/sponsors/repository/count.ts +4 -4
  298. package/server/erudit/staticFile.ts +28 -28
  299. package/server/plugins/augmentCss.ts +17 -17
  300. package/server/plugins/lang.ts +5 -7
  301. package/server/plugins/metaViewport.ts +15 -15
  302. package/server/plugins/theme.ts +13 -13
  303. package/server/routes/file/[...path].ts +18 -18
  304. package/server/routes/robots.txt.ts +9 -9
  305. package/server/routes/search.json.gz.ts +76 -73
  306. package/server/routes/sitemap.xml.ts +83 -81
  307. package/shared/search/encoders.ts +10 -10
  308. package/shared/types/asideMajorPages.ts +2 -2
  309. package/shared/types/breadcrumbs.ts +3 -3
  310. package/shared/types/contentChildren.ts +10 -10
  311. package/shared/types/contentConnections.ts +27 -27
  312. package/shared/types/contentStats.ts +6 -6
  313. package/shared/types/elementSnippet.ts +14 -14
  314. package/shared/types/frontContentNav.ts +17 -17
  315. package/shared/types/indexPage.ts +20 -20
  316. package/shared/types/language.ts +174 -174
  317. package/shared/types/mainContent.ts +40 -40
  318. package/shared/types/news.ts +13 -13
  319. package/shared/types/preview.ts +28 -28
  320. package/shared/types/runtimeConfig.ts +29 -47
  321. package/shared/types/search.ts +32 -32
  322. package/shared/utils/contentTypePath.ts +44 -44
  323. package/shared/utils/icons.ts +7 -7
  324. package/shared/utils/pages.ts +19 -20
  325. package/shared/utils/stringColor.ts +8 -8
  326. package/shared/utils/toStringEqual.ts +13 -13
  327. package/shared/utils/zip.ts +64 -64
  328. package/test/shared/utils/zip.test.ts +8 -8
  329. package/tsconfig.json +15 -15
  330. package/bin/erudit.mjs +0 -2
  331. package/modules/erudit/setup/aliases.ts +0 -17
  332. package/modules/erudit/setup/baseUrl.ts +0 -19
  333. package/modules/erudit/setup/nuxtConfig.ts +0 -62
  334. package/modules/erudit/setup/projectConfig.ts +0 -114
  335. package/shared/utils/slasher.ts +0 -64
  336. package/test/shared/utils/slasher.test.ts +0 -75
@@ -1,10 +1,10 @@
1
- export function getContributorAvatarUrl(
2
- contributorId: string,
3
- avatarExtension: string | undefined,
4
- ): string | undefined {
5
- if (!avatarExtension) {
6
- return undefined;
7
- }
8
-
9
- return '/file/contributors/' + contributorId + '/avatar.' + avatarExtension;
10
- }
1
+ export function getContributorAvatarUrl(
2
+ contributorId: string,
3
+ avatarExtension: string | undefined,
4
+ ): string | undefined {
5
+ if (!avatarExtension) {
6
+ return undefined;
7
+ }
8
+
9
+ return '/file/contributors/' + contributorId + '/avatar.' + avatarExtension;
10
+ }
@@ -1,178 +1,171 @@
1
- import { eq, count } from 'drizzle-orm';
2
- import type {
3
- ContentContribution,
4
- ContributorContribution,
5
- } from '@erudit-js/core/content/contributions';
6
-
7
- export async function countContributions(
8
- contributorId: string,
9
- ): Promise<number> {
10
- const result = await ERUDIT.db
11
- .select({ count: count() })
12
- .from(ERUDIT.db.schema.contentContributions)
13
- .where(
14
- eq(
15
- ERUDIT.db.schema.contentContributions.contributorId,
16
- contributorId,
17
- ),
18
- );
19
-
20
- return result[0].count;
21
- }
22
-
23
- export async function getContributorContributions(
24
- contributorId: string,
25
- ): Promise<ContributorContribution[] | undefined> {
26
- const contributions: ContributorContribution[] = [];
27
-
28
- const dbContributions = await ERUDIT.db.query.contentContributions.findMany(
29
- {
30
- columns: { contentFullId: true },
31
- where: eq(
32
- ERUDIT.db.schema.contentContributions.contributorId,
33
- contributorId,
34
- ),
35
- },
36
- );
37
-
38
- const contentFullIds = ERUDIT.contentNav.orderIds(
39
- dbContributions.map((c) => c.contentFullId),
40
- );
41
-
42
- const seenBookTitles = new Set<string>();
43
- let currentBookId: string | undefined;
44
-
45
- for (const contentFullId of contentFullIds) {
46
- const currentNode = ERUDIT.contentNav.getNodeOrThrow(contentFullId);
47
- const title = await ERUDIT.repository.content.title(
48
- contentFullId,
49
- 'normal',
50
- );
51
- const link = await ERUDIT.repository.content.link(contentFullId);
52
- const book = ERUDIT.contentNav.getBookFor(contentFullId);
53
-
54
- const contributionItem = {
55
- type: currentNode.type as 'topic' | 'page',
56
- title,
57
- link,
58
- };
59
-
60
- if (book && book.fullId === currentBookId) {
61
- // Add to existing book group
62
- const lastContribution = contributions.at(-1);
63
- if (lastContribution && lastContribution.type === 'book') {
64
- lastContribution.items.push(contributionItem);
65
- }
66
- } else if (book) {
67
- // Start a new book group
68
-
69
- currentBookId = book.fullId;
70
- const bookNode = ERUDIT.contentNav.getNodeOrThrow(book.fullId);
71
-
72
- const baseBookTitle = await ERUDIT.repository.content.title(
73
- book.fullId,
74
- 'normal',
75
- );
76
-
77
- let bookTitle = baseBookTitle;
78
-
79
- // Only include parent title if we've already seen a book with this title
80
- if (seenBookTitles.has(baseBookTitle) && bookNode.parent) {
81
- const parentTitle = await ERUDIT.repository.content.title(
82
- bookNode.parent.fullId,
83
- 'normal',
84
- );
85
- bookTitle = `${parentTitle} / ${baseBookTitle}`;
86
- }
87
-
88
- // Track this title for future duplicates
89
- seenBookTitles.add(baseBookTitle);
90
-
91
- contributions.push({
92
- type: 'book',
93
- title: bookTitle,
94
- items: [contributionItem],
95
- });
96
- } else {
97
- // Standalone contribution (not part of a book)
98
- currentBookId = undefined;
99
- contributions.push(contributionItem);
100
- }
101
- }
102
-
103
- return contributions.length > 0 ? contributions : undefined;
104
- }
105
-
106
- export async function getContentContributions(
107
- contentFullId: string,
108
- withDescription: boolean,
109
- ): Promise<ContentContribution[] | undefined> {
110
- const contributions: ContentContribution[] = [];
111
- const seenContributors = new Set<string>();
112
-
113
- const dbContributions = await ERUDIT.db.query.contentContributions.findMany(
114
- {
115
- columns: {
116
- contributorId: true,
117
- description: true,
118
- contentFullId: true,
119
- },
120
- },
121
- );
122
-
123
- const relevantContributions = dbContributions.filter(
124
- (dbContribution) =>
125
- dbContribution.contentFullId === contentFullId ||
126
- dbContribution.contentFullId.startsWith(`${contentFullId}/`),
127
- );
128
-
129
- for (const dbContribution of relevantContributions) {
130
- if (seenContributors.has(dbContribution.contributorId)) {
131
- continue;
132
- }
133
-
134
- seenContributors.add(dbContribution.contributorId);
135
-
136
- const dbContributor = await ERUDIT.db.query.contributors.findFirst({
137
- columns: {
138
- displayName: true,
139
- avatarExtension: true,
140
- },
141
- where: eq(
142
- ERUDIT.db.schema.contributors.contributorId,
143
- dbContribution.contributorId,
144
- ),
145
- });
146
-
147
- const name = dbContributor?.displayName || dbContribution.contributorId;
148
-
149
- const avatarUrl = ERUDIT.repository.contributors.avatarUrl(
150
- dbContribution.contributorId,
151
- dbContributor?.avatarExtension || undefined,
152
- );
153
-
154
- const description = withDescription
155
- ? dbContribution.description || undefined
156
- : undefined;
157
-
158
- const contribution: ContentContribution = {
159
- contributorId: dbContribution.contributorId,
160
- };
161
-
162
- if (name) {
163
- contribution.name = name;
164
- }
165
-
166
- if (avatarUrl) {
167
- contribution.avatarUrl = avatarUrl;
168
- }
169
-
170
- if (description) {
171
- contribution.description = description;
172
- }
173
-
174
- contributions.push(contribution);
175
- }
176
-
177
- return contributions.length > 0 ? contributions : undefined;
178
- }
1
+ import { eq, count } from 'drizzle-orm';
2
+ import type {
3
+ ContentContribution,
4
+ ContributorContribution,
5
+ } from '@erudit-js/core/content/contributions';
6
+
7
+ export async function countContributions(
8
+ contributorId: string,
9
+ ): Promise<number> {
10
+ const result = await ERUDIT.db
11
+ .select({ count: count() })
12
+ .from(ERUDIT.db.schema.contentContributions)
13
+ .where(
14
+ eq(ERUDIT.db.schema.contentContributions.contributorId, contributorId),
15
+ );
16
+
17
+ return result[0].count;
18
+ }
19
+
20
+ export async function getContributorContributions(
21
+ contributorId: string,
22
+ ): Promise<ContributorContribution[] | undefined> {
23
+ const contributions: ContributorContribution[] = [];
24
+
25
+ const dbContributions = await ERUDIT.db.query.contentContributions.findMany({
26
+ columns: { contentFullId: true },
27
+ where: eq(
28
+ ERUDIT.db.schema.contentContributions.contributorId,
29
+ contributorId,
30
+ ),
31
+ });
32
+
33
+ const contentFullIds = ERUDIT.contentNav.orderIds(
34
+ dbContributions.map((c) => c.contentFullId),
35
+ );
36
+
37
+ const seenBookTitles = new Set<string>();
38
+ let currentBookId: string | undefined;
39
+
40
+ for (const contentFullId of contentFullIds) {
41
+ const currentNode = ERUDIT.contentNav.getNodeOrThrow(contentFullId);
42
+ const title = await ERUDIT.repository.content.title(
43
+ contentFullId,
44
+ 'normal',
45
+ );
46
+ const link = await ERUDIT.repository.content.link(contentFullId);
47
+ const book = ERUDIT.contentNav.getBookFor(contentFullId);
48
+
49
+ const contributionItem = {
50
+ type: currentNode.type as 'topic' | 'page',
51
+ title,
52
+ link,
53
+ };
54
+
55
+ if (book && book.fullId === currentBookId) {
56
+ // Add to existing book group
57
+ const lastContribution = contributions.at(-1);
58
+ if (lastContribution && lastContribution.type === 'book') {
59
+ lastContribution.items.push(contributionItem);
60
+ }
61
+ } else if (book) {
62
+ // Start a new book group
63
+
64
+ currentBookId = book.fullId;
65
+ const bookNode = ERUDIT.contentNav.getNodeOrThrow(book.fullId);
66
+
67
+ const baseBookTitle = await ERUDIT.repository.content.title(
68
+ book.fullId,
69
+ 'normal',
70
+ );
71
+
72
+ let bookTitle = baseBookTitle;
73
+
74
+ // Only include parent title if we've already seen a book with this title
75
+ if (seenBookTitles.has(baseBookTitle) && bookNode.parent) {
76
+ const parentTitle = await ERUDIT.repository.content.title(
77
+ bookNode.parent.fullId,
78
+ 'normal',
79
+ );
80
+ bookTitle = `${parentTitle} / ${baseBookTitle}`;
81
+ }
82
+
83
+ // Track this title for future duplicates
84
+ seenBookTitles.add(baseBookTitle);
85
+
86
+ contributions.push({
87
+ type: 'book',
88
+ title: bookTitle,
89
+ items: [contributionItem],
90
+ });
91
+ } else {
92
+ // Standalone contribution (not part of a book)
93
+ currentBookId = undefined;
94
+ contributions.push(contributionItem);
95
+ }
96
+ }
97
+
98
+ return contributions.length > 0 ? contributions : undefined;
99
+ }
100
+
101
+ export async function getContentContributions(
102
+ contentFullId: string,
103
+ withDescription: boolean,
104
+ ): Promise<ContentContribution[] | undefined> {
105
+ const contributions: ContentContribution[] = [];
106
+ const seenContributors = new Set<string>();
107
+
108
+ const dbContributions = await ERUDIT.db.query.contentContributions.findMany({
109
+ columns: {
110
+ contributorId: true,
111
+ description: true,
112
+ contentFullId: true,
113
+ },
114
+ });
115
+
116
+ const relevantContributions = dbContributions.filter(
117
+ (dbContribution) =>
118
+ dbContribution.contentFullId === contentFullId ||
119
+ dbContribution.contentFullId.startsWith(`${contentFullId}/`),
120
+ );
121
+
122
+ for (const dbContribution of relevantContributions) {
123
+ if (seenContributors.has(dbContribution.contributorId)) {
124
+ continue;
125
+ }
126
+
127
+ seenContributors.add(dbContribution.contributorId);
128
+
129
+ const dbContributor = await ERUDIT.db.query.contributors.findFirst({
130
+ columns: {
131
+ displayName: true,
132
+ avatarExtension: true,
133
+ },
134
+ where: eq(
135
+ ERUDIT.db.schema.contributors.contributorId,
136
+ dbContribution.contributorId,
137
+ ),
138
+ });
139
+
140
+ const name = dbContributor?.displayName || dbContribution.contributorId;
141
+
142
+ const avatarUrl = ERUDIT.repository.contributors.avatarUrl(
143
+ dbContribution.contributorId,
144
+ dbContributor?.avatarExtension || undefined,
145
+ );
146
+
147
+ const description = withDescription
148
+ ? dbContribution.description || undefined
149
+ : undefined;
150
+
151
+ const contribution: ContentContribution = {
152
+ contributorId: dbContribution.contributorId,
153
+ };
154
+
155
+ if (name) {
156
+ contribution.name = name;
157
+ }
158
+
159
+ if (avatarUrl) {
160
+ contribution.avatarUrl = avatarUrl;
161
+ }
162
+
163
+ if (description) {
164
+ contribution.description = description;
165
+ }
166
+
167
+ contributions.push(contribution);
168
+ }
169
+
170
+ return contributions.length > 0 ? contributions : undefined;
171
+ }
@@ -1,3 +1,3 @@
1
- export function countContributors(): number {
2
- return Object.values($CONTRIBUTOR).length;
3
- }
1
+ export function countContributors(): number {
2
+ return Object.values($CONTRIBUTOR).length;
3
+ }
@@ -1,34 +1,34 @@
1
- export const searchCategoryContributors: SearchEntryCategory = {
2
- id: 'contributors',
3
- priority: 100,
4
- };
5
-
6
- export async function searchIndexContributors(): Promise<SearchEntriesList> {
7
- const dbContributors = await ERUDIT.db.query.contributors.findMany({
8
- columns: {
9
- contributorId: true,
10
- displayName: true,
11
- },
12
- });
13
-
14
- return {
15
- category: searchCategoryContributors,
16
- entries: dbContributors.map((dbContributor) => {
17
- const entry: SearchEntry = {
18
- category: searchCategoryContributors.id,
19
- title: dbContributor.displayName || dbContributor.contributorId,
20
- link: PAGES.contributor(dbContributor.contributorId),
21
- };
22
-
23
- const hasDisplayName = !!dbContributor.displayName;
24
- const displaySameAsId =
25
- dbContributor.displayName === dbContributor.contributorId;
26
-
27
- if (hasDisplayName && !displaySameAsId) {
28
- entry.synonyms = [dbContributor.contributorId];
29
- }
30
-
31
- return entry;
32
- }),
33
- };
34
- }
1
+ export const searchCategoryContributors: SearchEntryCategory = {
2
+ id: 'contributors',
3
+ priority: 100,
4
+ };
5
+
6
+ export async function searchIndexContributors(): Promise<SearchEntriesList> {
7
+ const dbContributors = await ERUDIT.db.query.contributors.findMany({
8
+ columns: {
9
+ contributorId: true,
10
+ displayName: true,
11
+ },
12
+ });
13
+
14
+ return {
15
+ category: searchCategoryContributors,
16
+ entries: dbContributors.map((dbContributor) => {
17
+ const entry: SearchEntry = {
18
+ category: searchCategoryContributors.id,
19
+ title: dbContributor.displayName || dbContributor.contributorId,
20
+ link: PAGES.contributor(dbContributor.contributorId),
21
+ };
22
+
23
+ const hasDisplayName = !!dbContributor.displayName;
24
+ const displaySameAsId =
25
+ dbContributor.displayName === dbContributor.contributorId;
26
+
27
+ if (hasDisplayName && !displaySameAsId) {
28
+ entry.synonyms = [dbContributor.contributorId];
29
+ }
30
+
31
+ return entry;
32
+ }),
33
+ };
34
+ }
@@ -1,26 +1,23 @@
1
- import slash from 'slash';
2
-
3
- export async function pushFile(filepath: string, role: string): Promise<void> {
4
- filepath = slash(filepath);
5
-
6
- if (!filepath.startsWith(ERUDIT.config.paths.project)) {
7
- throw createError({
8
- statusCode: 400,
9
- statusMessage: 'File is outside of project directory!',
10
- message: `Can not add ${filepath} as it is outside of the project directory!`,
11
- });
12
- }
13
-
14
- const relativePath = filepath.replace(
15
- ERUDIT.config.paths.project + '/',
16
- '',
17
- );
18
-
19
- await ERUDIT.db
20
- .insert(ERUDIT.db.schema.files)
21
- .values({
22
- path: relativePath,
23
- role,
24
- })
25
- .onConflictDoNothing();
26
- }
1
+ import { sn } from 'unslash';
2
+
3
+ export async function pushFile(filepath: string, role: string): Promise<void> {
4
+ filepath = sn(filepath);
5
+
6
+ if (!filepath.startsWith(ERUDIT.paths.project())) {
7
+ throw createError({
8
+ statusCode: 400,
9
+ statusMessage: 'File is outside of project directory!',
10
+ message: `Can not add ${filepath} as it is outside of the project directory!`,
11
+ });
12
+ }
13
+
14
+ const relativePath = filepath.replace(ERUDIT.paths.project() + '/', '');
15
+
16
+ await ERUDIT.db
17
+ .insert(ERUDIT.db.schema.files)
18
+ .values({
19
+ path: relativePath,
20
+ role,
21
+ })
22
+ .onConflictDoNothing();
23
+ }
@@ -1,19 +1,19 @@
1
- export async function pushProblemScript(
2
- problemScriptSrc: string,
3
- contentFullId: string,
4
- ): Promise<void> {
5
- const parsedId = problemScriptSrc;
6
-
7
- if (!problemScriptSrc.startsWith(ERUDIT.config.paths.project)) {
8
- throw createError({
9
- statusCode: 400,
10
- statusMessage: 'Problem script is outside of project directory!',
11
- message: `Can not add problem script from ${problemScriptSrc} as it is outside of the project directory!`,
12
- });
13
- }
14
-
15
- await ERUDIT.db.insert(ERUDIT.db.schema.problemScripts).values({
16
- problemScriptSrc,
17
- contentFullId,
18
- });
19
- }
1
+ export async function pushProblemScript(
2
+ problemScriptSrc: string,
3
+ contentFullId: string,
4
+ ): Promise<void> {
5
+ const parsedId = problemScriptSrc;
6
+
7
+ if (!problemScriptSrc.startsWith(ERUDIT.paths.project())) {
8
+ throw createError({
9
+ statusCode: 400,
10
+ statusMessage: 'Problem script is outside of project directory!',
11
+ message: `Can not add problem script from ${problemScriptSrc} as it is outside of the project directory!`,
12
+ });
13
+ }
14
+
15
+ await ERUDIT.db.insert(ERUDIT.db.schema.problemScripts).values({
16
+ problemScriptSrc,
17
+ contentFullId,
18
+ });
19
+ }
@@ -1,40 +1,40 @@
1
- import {
2
- isContentProseType,
3
- type ContentProseType,
4
- } from '@erudit-js/core/content/prose';
5
- import type { ProseLink } from '@erudit-js/core/prose/link';
6
-
7
- export async function pushProseLink(
8
- contentFullId: string,
9
- contentProseType: ContentProseType,
10
- proseLink: ProseLink,
11
- ): Promise<void> {
12
- let toContentId: string | undefined;
13
- let toContentProseType: ContentProseType | undefined;
14
-
15
- switch (proseLink.type) {
16
- case 'contentItem':
17
- toContentId = proseLink.itemId.contentId;
18
- isContentProseType(proseLink.itemId.type) &&
19
- (toContentProseType = proseLink.itemId.type);
20
- break;
21
- case 'document':
22
- case 'unique':
23
- if (proseLink.documentId.type === 'contentPage') {
24
- toContentId = proseLink.documentId.contentId;
25
- toContentProseType = 'page';
26
- } else if (proseLink.documentId.type === 'contentTopic') {
27
- toContentId = proseLink.documentId.contentId;
28
- toContentProseType = proseLink.documentId.topicPart;
29
- }
30
- break;
31
- }
32
-
33
- await ERUDIT.db.insert(ERUDIT.db.schema.contentProseLinks).values({
34
- fromContentId: contentFullId,
35
- fromContentProseType: contentProseType,
36
- toContentId,
37
- toContentProseType,
38
- proseLink,
39
- });
40
- }
1
+ import {
2
+ isContentProseType,
3
+ type ContentProseType,
4
+ } from '@erudit-js/core/content/prose';
5
+ import type { ProseLink } from '@erudit-js/core/prose/link';
6
+
7
+ export async function pushProseLink(
8
+ contentFullId: string,
9
+ contentProseType: ContentProseType,
10
+ proseLink: ProseLink,
11
+ ): Promise<void> {
12
+ let toContentId: string | undefined;
13
+ let toContentProseType: ContentProseType | undefined;
14
+
15
+ switch (proseLink.type) {
16
+ case 'contentItem':
17
+ toContentId = proseLink.itemId.contentId;
18
+ isContentProseType(proseLink.itemId.type) &&
19
+ (toContentProseType = proseLink.itemId.type);
20
+ break;
21
+ case 'document':
22
+ case 'unique':
23
+ if (proseLink.documentId.type === 'contentPage') {
24
+ toContentId = proseLink.documentId.contentId;
25
+ toContentProseType = 'page';
26
+ } else if (proseLink.documentId.type === 'contentTopic') {
27
+ toContentId = proseLink.documentId.contentId;
28
+ toContentProseType = proseLink.documentId.topicPart;
29
+ }
30
+ break;
31
+ }
32
+
33
+ await ERUDIT.db.insert(ERUDIT.db.schema.contentProseLinks).values({
34
+ fromContentId: contentFullId,
35
+ fromContentProseType: contentProseType,
36
+ toContentId,
37
+ toContentProseType,
38
+ proseLink,
39
+ });
40
+ }
@@ -1,7 +1,7 @@
1
- import { sqliteTable, text } from 'drizzle-orm/sqlite-core';
2
- import type { Cameo } from '@erudit-js/core/cameo';
3
-
4
- export const cameos = sqliteTable('cameos', {
5
- cameoId: text().primaryKey(),
6
- data: text({ mode: 'json' }).notNull().$type<Cameo>(),
7
- });
1
+ import { sqliteTable, text } from 'drizzle-orm/sqlite-core';
2
+ import type { Cameo } from '@erudit-js/core/cameo';
3
+
4
+ export const cameos = sqliteTable('cameos', {
5
+ cameoId: text().primaryKey(),
6
+ data: text({ mode: 'json' }).notNull().$type<Cameo>(),
7
+ });