erudit 4.0.0-dev.5 → 4.0.1

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 (361) hide show
  1. package/app/app.vue +34 -34
  2. package/app/assets/icons/array-check.svg +2 -2
  3. package/app/assets/icons/array-lines.svg +2 -2
  4. package/app/assets/icons/array-star.svg +2 -2
  5. package/app/assets/icons/arrow/from-circle.svg +2 -2
  6. package/app/assets/icons/arrow/left.svg +2 -2
  7. package/app/assets/icons/arrow/outward.svg +2 -2
  8. package/app/assets/icons/arrow/to-circle.svg +2 -2
  9. package/app/assets/icons/arrow/up-to-right.svg +2 -2
  10. package/app/assets/icons/aside-open.svg +2 -2
  11. package/app/assets/icons/asterisk.svg +2 -2
  12. package/app/assets/icons/book-question.svg +2 -2
  13. package/app/assets/icons/construction.svg +2 -2
  14. package/app/assets/icons/draw.svg +2 -2
  15. package/app/assets/icons/erudit.svg +2 -2
  16. package/app/assets/icons/file-lines.svg +2 -2
  17. package/app/assets/icons/files.svg +2 -2
  18. package/app/assets/icons/folder-open.svg +2 -2
  19. package/app/assets/icons/folder.svg +2 -2
  20. package/app/assets/icons/graduation.svg +2 -2
  21. package/app/assets/icons/handshake.svg +2 -2
  22. package/app/assets/icons/lines.svg +2 -2
  23. package/app/assets/icons/plus-circle.svg +2 -2
  24. package/app/assets/icons/puzzle.svg +2 -2
  25. package/app/assets/icons/rocket.svg +2 -2
  26. package/app/assets/icons/search/check.svg +2 -2
  27. package/app/assets/icons/search/dead.svg +2 -2
  28. package/app/assets/icons/search/glass.svg +2 -2
  29. package/app/assets/icons/search/wtf.svg +2 -2
  30. package/app/assets/icons/sun-moon.svg +2 -2
  31. package/app/assets/icons/translate.svg +2 -2
  32. package/app/assets/icons/warning.svg +2 -2
  33. package/app/components/EruditLink.ts +9 -9
  34. package/app/components/FancyBold.vue +16 -16
  35. package/app/components/FancyCard.vue +52 -52
  36. package/app/components/FancyCardTag.vue +16 -16
  37. package/app/components/Loading.vue +7 -7
  38. package/app/components/Prose.vue +55 -55
  39. package/app/components/ScrollHolder.vue +20 -20
  40. package/app/components/SmartMedia.vue +107 -107
  41. package/app/components/ads/Ads.vue +39 -39
  42. package/app/components/ads/AdsBannerAside.vue +45 -45
  43. package/app/components/ads/AdsBannerBottom.vue +17 -17
  44. package/app/components/ads/AdsReplacer.vue +26 -26
  45. package/app/components/ads/provider/Custom.vue +19 -19
  46. package/app/components/ads/provider/Yandex.vue +84 -84
  47. package/app/components/aside/AsideListItem.vue +61 -61
  48. package/app/components/aside/AsideMajor.vue +8 -8
  49. package/app/components/aside/AsideMinor.vue +68 -68
  50. package/app/components/aside/AsidePlainMessage.vue +9 -9
  51. package/app/components/aside/AsideSwitch.vue +76 -76
  52. package/app/components/aside/major/PaneHolder.vue +106 -106
  53. package/app/components/aside/major/PaneSwitcher.vue +68 -68
  54. package/app/components/aside/major/PaneSwitcherButton.vue +38 -38
  55. package/app/components/aside/major/PaneTemplate.vue +5 -5
  56. package/app/components/aside/major/SiteInfo.vue +66 -66
  57. package/app/components/aside/major/contentNav/PaneBookNav.vue +107 -107
  58. package/app/components/aside/major/contentNav/PaneGlobalNav.vue +19 -19
  59. package/app/components/aside/major/contentNav/items/ContentNavBook.vue +21 -21
  60. package/app/components/aside/major/contentNav/items/ContentNavFolder.vue +91 -91
  61. package/app/components/aside/major/contentNav/items/ContentNavItem.vue +33 -33
  62. package/app/components/aside/major/contentNav/items/ContentNavPage.vue +14 -14
  63. package/app/components/aside/major/contentNav/items/ContentNavSeparator.vue +61 -61
  64. package/app/components/aside/major/contentNav/items/ContentNavTopic.vue +18 -18
  65. package/app/components/aside/major/contentNav/items/Flags.vue +50 -50
  66. package/app/components/aside/major/contentNav/items/ItemTemplate.vue +27 -27
  67. package/app/components/aside/major/languages/PaneLanguages.vue +55 -55
  68. package/app/components/aside/major/pages/PanePages.vue +60 -60
  69. package/app/components/aside/major/search/PaneSearch.vue +156 -156
  70. package/app/components/aside/major/search/SearchInput.vue +103 -103
  71. package/app/components/aside/major/search/SearchResult.vue +154 -154
  72. package/app/components/aside/major/search/SearchStatus.vue +48 -48
  73. package/app/components/aside/major/search/search.worker.ts +164 -164
  74. package/app/components/aside/major/settings/BuildTime.vue +25 -25
  75. package/app/components/aside/major/settings/EngineVersion.vue +14 -14
  76. package/app/components/aside/major/settings/PaneSettings.vue +17 -17
  77. package/app/components/aside/major/settings/ThemeSwitcher.vue +55 -55
  78. package/app/components/aside/major/settings/repository/Repository.vue +33 -33
  79. package/app/components/aside/major/settings/repository/SecondaryGitHub.vue +71 -71
  80. package/app/components/aside/minor/AsideMinorPane.vue +5 -5
  81. package/app/components/aside/minor/AsideMinorPlainHeader.vue +20 -20
  82. package/app/components/aside/minor/content/AsideMinorContentContributions.vue +47 -47
  83. package/app/components/aside/minor/content/AsideMinorContentPage.vue +37 -37
  84. package/app/components/aside/minor/content/AsideMinorContentTopic.vue +61 -61
  85. package/app/components/aside/minor/content/ButtonPaneContributions.vue +101 -101
  86. package/app/components/aside/minor/content/ButtonPaneImprove.vue +112 -112
  87. package/app/components/aside/minor/content/Contribution.vue +36 -36
  88. package/app/components/aside/minor/content/Toc.vue +163 -163
  89. package/app/components/aside/minor/content/TocItem.vue +91 -91
  90. package/app/components/aside/minor/content/TopicPartButton.vue +35 -35
  91. package/app/components/aside/minor/contributor/AsideMinorContributor.vue +36 -36
  92. package/app/components/aside/minor/contributor/ItemBook.vue +33 -33
  93. package/app/components/aside/minor/contributor/ItemContent.vue +17 -17
  94. package/app/components/aside/minor/news/AsideMinorNews.vue +132 -132
  95. package/app/components/aside/minor/news/NewsItem.vue +69 -69
  96. package/app/components/aside/minor/news/RenderNewsElement.vue +42 -42
  97. package/app/components/aside/minor/news/elements/Mix.vue +11 -11
  98. package/app/components/aside/minor/news/elements/P.vue +14 -14
  99. package/app/components/aside/minor/news/elements/Ref.vue +59 -59
  100. package/app/components/aside/minor/news/elements/Text.vue +18 -18
  101. package/app/components/indexPage/IndexPagePersons.vue +116 -116
  102. package/app/components/main/MainAction.vue +26 -26
  103. package/app/components/main/MainBreadcrumbs.vue +28 -28
  104. package/app/components/main/MainContentChild.vue +44 -44
  105. package/app/components/main/MainContentChildren.vue +13 -13
  106. package/app/components/main/MainDecoration.vue +15 -15
  107. package/app/components/main/MainDescription.vue +13 -13
  108. package/app/components/main/MainFlag.vue +129 -129
  109. package/app/components/main/MainFlags.vue +17 -17
  110. package/app/components/main/MainGlow.vue +12 -12
  111. package/app/components/main/MainQuickLink.vue +90 -90
  112. package/app/components/main/MainQuickLinks.vue +40 -40
  113. package/app/components/main/MainQuote.vue +149 -149
  114. package/app/components/main/MainQuoteLoader.vue +86 -86
  115. package/app/components/main/MainSection.vue +44 -44
  116. package/app/components/main/MainSectionPreamble.vue +5 -5
  117. package/app/components/main/MainSubTitle.vue +11 -11
  118. package/app/components/main/MainTitle.vue +32 -32
  119. package/app/components/main/MainTopicPartPage.vue +88 -88
  120. package/app/components/main/MainTopicPartSwitch.vue +67 -67
  121. package/app/components/main/connections/Deps.vue +30 -30
  122. package/app/components/main/connections/Externals.vue +80 -80
  123. package/app/components/main/connections/MainConnections.vue +90 -90
  124. package/app/components/main/connections/MainConnectionsButton.vue +81 -81
  125. package/app/components/main/connections/ScrollPane.vue +10 -10
  126. package/app/components/main/contentStats/Item.vue +28 -28
  127. package/app/components/main/contentStats/ItemElement.vue +19 -19
  128. package/app/components/main/contentStats/ItemMaterials.vue +11 -11
  129. package/app/components/main/contentStats/MainContentStats.vue +50 -50
  130. package/app/components/preview/Preview.vue +161 -161
  131. package/app/components/preview/PreviewError.vue +10 -10
  132. package/app/components/preview/PreviewLoading.vue +5 -5
  133. package/app/components/preview/PreviewScreen.vue +64 -64
  134. package/app/components/preview/PreviewScreenButton.vue +39 -39
  135. package/app/components/preview/screen/ContentPage.vue +47 -47
  136. package/app/components/preview/screen/DirectLink.vue +23 -23
  137. package/app/components/preview/screen/Unique.vue +53 -53
  138. package/app/components/site/SiteAside.vue +67 -67
  139. package/app/components/site/SiteAsideOverlay.vue +21 -21
  140. package/app/components/site/SiteMain.vue +13 -13
  141. package/app/components/transition/Fade.vue +30 -30
  142. package/app/components/transition/Slide.vue +47 -47
  143. package/app/components/tree/TreeContainer.vue +5 -5
  144. package/app/components/tree/TreeItem.vue +36 -36
  145. package/app/composables/ads.ts +23 -23
  146. package/app/composables/analytics.ts +102 -102
  147. package/app/composables/appElements.ts +40 -40
  148. package/app/composables/aside.ts +28 -28
  149. package/app/composables/asideMajorPane.ts +135 -135
  150. package/app/composables/asideMinor.ts +109 -109
  151. package/app/composables/contentNav.ts +7 -7
  152. package/app/composables/favicon.ts +103 -103
  153. package/app/composables/file.ts +4 -4
  154. package/app/composables/formatText.ts +100 -100
  155. package/app/composables/loading.ts +26 -26
  156. package/app/composables/mainContent.ts +31 -31
  157. package/app/composables/og.ts +184 -184
  158. package/app/composables/phrases.ts +126 -126
  159. package/app/composables/preview.ts +53 -53
  160. package/app/composables/route.ts +6 -6
  161. package/app/composables/theme.ts +67 -67
  162. package/app/composables/url.ts +30 -30
  163. package/app/formatters/ru.ts +14 -14
  164. package/app/pages/article/[...articleId].vue +12 -12
  165. package/app/pages/book/[...bookId].vue +56 -56
  166. package/app/pages/contributor/[contributorId].vue +144 -144
  167. package/app/pages/contributors.vue +95 -95
  168. package/app/pages/group/[...groupId].vue +58 -58
  169. package/app/pages/index.vue +113 -113
  170. package/app/pages/page/[...pageId].vue +60 -60
  171. package/app/pages/practice/[...practiceId].vue +12 -12
  172. package/app/pages/sponsors.vue +88 -88
  173. package/app/pages/summary/[...summaryId].vue +12 -12
  174. package/app/plugins/appSetup/client/htmlBranding.ts +6 -6
  175. package/app/plugins/appSetup/client/welcome.ts +37 -37
  176. package/app/plugins/appSetup/config.ts +6 -6
  177. package/app/plugins/appSetup/global.ts +3 -3
  178. package/app/plugins/appSetup/index.ts +27 -27
  179. package/app/plugins/prerender.server.ts +40 -40
  180. package/app/router.options.ts +5 -5
  181. package/app/scripts/theme.js +30 -30
  182. package/app/styles/main.css +176 -176
  183. package/bin/erudit.js +12 -12
  184. package/modules/erudit/env.ts +8 -8
  185. package/modules/erudit/globals/content.ts +4 -4
  186. package/modules/erudit/globals/contributor.ts +1 -1
  187. package/modules/erudit/globals/eruditConfig.ts +5 -5
  188. package/modules/erudit/globals/problem.ts +1 -1
  189. package/modules/erudit/globals/prose.ts +5 -1
  190. package/modules/erudit/globals/public.ts +18 -18
  191. package/modules/erudit/index.ts +50 -50
  192. package/modules/erudit/logger.ts +10 -10
  193. package/modules/erudit/setup/elements/appTemplate.ts +44 -44
  194. package/modules/erudit/setup/elements/globalTemplate.ts +82 -82
  195. package/modules/erudit/setup/elements/globalTypes.ts +259 -259
  196. package/modules/erudit/setup/elements/setup.ts +163 -163
  197. package/modules/erudit/setup/elements/shared.ts +10 -10
  198. package/modules/erudit/setup/elements/tagsTable.ts +28 -28
  199. package/modules/erudit/setup/fullRestart.ts +61 -61
  200. package/modules/erudit/setup/globals.ts +210 -206
  201. package/modules/erudit/setup/publicAssets.ts +43 -43
  202. package/modules/erudit/setup/runtimeConfig.ts +106 -106
  203. package/modules/erudit/watcher.ts +20 -20
  204. package/nuxt.config.ts +102 -102
  205. package/package.json +5 -5
  206. package/proxy/prose.app.ts +1 -1
  207. package/proxy/prose.ts +1 -1
  208. package/server/api/aside/major/frontNav/book/[...shortId].ts +10 -10
  209. package/server/api/aside/major/frontNav/global.ts +5 -5
  210. package/server/api/aside/major/pages.ts +6 -6
  211. package/server/api/contributor/list.ts +60 -60
  212. package/server/api/contributor/page/[contributorId].ts +68 -68
  213. package/server/api/indexPage.ts +81 -81
  214. package/server/api/language/functions.ts +11 -11
  215. package/server/api/language/phrase/[phraseKey].ts +35 -35
  216. package/server/api/main/content/[...contentTypePath].ts +149 -149
  217. package/server/api/news/batch/[batchIndex].ts +5 -5
  218. package/server/api/pageSponsors.ts +56 -56
  219. package/server/api/prerender/content.ts +79 -79
  220. package/server/api/prerender/default.ts +35 -35
  221. package/server/api/prerender/files.ts +10 -10
  222. package/server/api/prerender/frontNav.ts +13 -13
  223. package/server/api/prerender/language.ts +7 -7
  224. package/server/api/prerender/news.ts +8 -8
  225. package/server/api/prerender/quotes.ts +15 -15
  226. package/server/api/preview/contentPage/[...contentTypePath].ts +63 -63
  227. package/server/api/preview/contentUnique/[...contentTypePathUnique].ts +73 -73
  228. package/server/api/problemScript/[...problemScriptPath].ts +88 -88
  229. package/server/api/quote/data/[quoteId].ts +84 -84
  230. package/server/api/quote/ids.ts +3 -3
  231. package/server/erudit/build.ts +132 -132
  232. package/server/erudit/cameos/build.ts +161 -161
  233. package/server/erudit/config.ts +13 -13
  234. package/server/erudit/content/global/build.ts +300 -300
  235. package/server/erudit/content/global/singleton.ts +5 -5
  236. package/server/erudit/content/nav/build.ts +459 -459
  237. package/server/erudit/content/nav/front.ts +125 -125
  238. package/server/erudit/content/nav/repository/books.ts +37 -37
  239. package/server/erudit/content/nav/repository/get.ts +33 -33
  240. package/server/erudit/content/nav/repository/hasChildren.ts +5 -5
  241. package/server/erudit/content/nav/repository/hasNav.ts +3 -3
  242. package/server/erudit/content/nav/repository/hasParent.ts +5 -5
  243. package/server/erudit/content/nav/repository/id.ts +9 -9
  244. package/server/erudit/content/nav/repository/index.ts +9 -9
  245. package/server/erudit/content/nav/repository/order.ts +14 -14
  246. package/server/erudit/content/nav/repository/previousNext.ts +35 -35
  247. package/server/erudit/content/nav/repository/walk.ts +127 -127
  248. package/server/erudit/content/nav/setup.ts +13 -13
  249. package/server/erudit/content/nav/types.ts +24 -24
  250. package/server/erudit/content/repository/breadcrumbs.ts +24 -24
  251. package/server/erudit/content/repository/children.ts +47 -47
  252. package/server/erudit/content/repository/connections.ts +35 -35
  253. package/server/erudit/content/repository/contentLink.ts +16 -16
  254. package/server/erudit/content/repository/decoration.ts +23 -23
  255. package/server/erudit/content/repository/deps.ts +121 -121
  256. package/server/erudit/content/repository/description.ts +11 -11
  257. package/server/erudit/content/repository/elementSnippets.ts +105 -105
  258. package/server/erudit/content/repository/externals.ts +50 -50
  259. package/server/erudit/content/repository/flags.ts +33 -33
  260. package/server/erudit/content/repository/seo.ts +12 -12
  261. package/server/erudit/content/repository/stats.ts +97 -97
  262. package/server/erudit/content/repository/title.ts +27 -27
  263. package/server/erudit/content/repository/topicParts.ts +39 -39
  264. package/server/erudit/content/repository/unique.ts +76 -76
  265. package/server/erudit/content/resolve/book.ts +29 -29
  266. package/server/erudit/content/resolve/group.ts +34 -34
  267. package/server/erudit/content/resolve/index.ts +272 -272
  268. package/server/erudit/content/resolve/page.ts +80 -80
  269. package/server/erudit/content/resolve/topic.ts +220 -220
  270. package/server/erudit/content/resolve/utils/contentError.ts +10 -10
  271. package/server/erudit/content/resolve/utils/insertContentItem.ts +113 -113
  272. package/server/erudit/content/resolve/utils/insertContentResolved.ts +126 -126
  273. package/server/erudit/content/search.ts +146 -146
  274. package/server/erudit/contributors/build.ts +158 -158
  275. package/server/erudit/contributors/global.ts +3 -3
  276. package/server/erudit/contributors/repository/avatarUrl.ts +10 -10
  277. package/server/erudit/contributors/repository/contributions.ts +171 -171
  278. package/server/erudit/contributors/repository/count.ts +3 -3
  279. package/server/erudit/contributors/search.ts +34 -34
  280. package/server/erudit/db/repository/pushFile.ts +23 -23
  281. package/server/erudit/db/repository/pushProblemScript.ts +19 -19
  282. package/server/erudit/db/repository/pushProseLink.ts +40 -40
  283. package/server/erudit/db/schema/cameos.ts +7 -7
  284. package/server/erudit/db/schema/content.ts +18 -18
  285. package/server/erudit/db/schema/contentContributions.ts +15 -15
  286. package/server/erudit/db/schema/contentDeps.ts +21 -21
  287. package/server/erudit/db/schema/contentElementStats.ts +20 -20
  288. package/server/erudit/db/schema/contentProseLinks.ts +23 -23
  289. package/server/erudit/db/schema/contentSnippets.ts +15 -15
  290. package/server/erudit/db/schema/contentToc.ts +16 -16
  291. package/server/erudit/db/schema/contentUniques.ts +19 -19
  292. package/server/erudit/db/schema/contributors.ts +12 -12
  293. package/server/erudit/db/schema/files.ts +11 -11
  294. package/server/erudit/db/schema/groups.ts +6 -6
  295. package/server/erudit/db/schema/index.ts +17 -17
  296. package/server/erudit/db/schema/news.ts +7 -7
  297. package/server/erudit/db/schema/pages.ts +7 -7
  298. package/server/erudit/db/schema/problemScripts.ts +14 -14
  299. package/server/erudit/db/schema/sponsors.ts +9 -9
  300. package/server/erudit/db/schema/topics.ts +9 -9
  301. package/server/erudit/db/setup.ts +62 -62
  302. package/server/erudit/db/types.ts +10 -10
  303. package/server/erudit/global.ts +38 -38
  304. package/server/erudit/importer.ts +94 -94
  305. package/server/erudit/index.ts +96 -96
  306. package/server/erudit/language/list/en.ts +116 -116
  307. package/server/erudit/language/list/ru.ts +120 -120
  308. package/server/erudit/language/list.ts +6 -6
  309. package/server/erudit/language/setup.ts +36 -36
  310. package/server/erudit/language/types.ts +16 -16
  311. package/server/erudit/logger.ts +73 -73
  312. package/server/erudit/news/build.ts +112 -112
  313. package/server/erudit/news/repository/batch.ts +61 -61
  314. package/server/erudit/path.ts +19 -19
  315. package/server/erudit/prose/repository/finalize.ts +68 -68
  316. package/server/erudit/prose/repository/get.ts +54 -54
  317. package/server/erudit/prose/repository/resolve.ts +17 -17
  318. package/server/erudit/prose/storage/callout.ts +16 -16
  319. package/server/erudit/prose/storage/image.ts +22 -22
  320. package/server/erudit/prose/storage/link.ts +222 -222
  321. package/server/erudit/prose/storage/problemScript.ts +23 -23
  322. package/server/erudit/prose/storage/video.ts +16 -16
  323. package/server/erudit/prose/transform/bundleProblemScript.ts +6 -6
  324. package/server/erudit/prose/transform/extensions.ts +15 -15
  325. package/server/erudit/quote/repository/ids.ts +31 -31
  326. package/server/erudit/repository.ts +96 -96
  327. package/server/erudit/sponsors/build.ts +161 -161
  328. package/server/erudit/sponsors/repository/avatarUrl.ts +10 -10
  329. package/server/erudit/sponsors/repository/count.ts +4 -4
  330. package/server/erudit/staticFile.ts +28 -28
  331. package/server/plugins/augmentCss.ts +17 -17
  332. package/server/plugins/lang.ts +5 -5
  333. package/server/plugins/metaViewport.ts +15 -15
  334. package/server/plugins/theme.ts +13 -13
  335. package/server/routes/file/[...path].ts +18 -18
  336. package/server/routes/robots.txt.ts +9 -9
  337. package/server/routes/search.json.gz.ts +76 -76
  338. package/server/routes/sitemap.xml.ts +83 -83
  339. package/shared/search/encoders.ts +20 -20
  340. package/shared/types/asideMajorPages.ts +4 -4
  341. package/shared/types/breadcrumbs.ts +9 -9
  342. package/shared/types/contentChildren.ts +10 -10
  343. package/shared/types/contentConnections.ts +27 -27
  344. package/shared/types/contentStats.ts +6 -6
  345. package/shared/types/elementSnippet.ts +14 -14
  346. package/shared/types/frontContentNav.ts +38 -38
  347. package/shared/types/indexPage.ts +20 -20
  348. package/shared/types/language.ts +191 -191
  349. package/shared/types/mainContent.ts +69 -69
  350. package/shared/types/news.ts +13 -13
  351. package/shared/types/preview.ts +28 -28
  352. package/shared/types/runtimeConfig.ts +46 -46
  353. package/shared/types/search.ts +79 -79
  354. package/shared/utils/contentTypePath.ts +63 -63
  355. package/shared/utils/icons.ts +11 -11
  356. package/shared/utils/pages.ts +23 -23
  357. package/shared/utils/stringColor.ts +13 -13
  358. package/shared/utils/toStringEqual.ts +21 -21
  359. package/shared/utils/zip.ts +64 -64
  360. package/test/shared/utils/zip.test.ts +8 -8
  361. package/tsconfig.json +17 -17
@@ -1,300 +1,300 @@
1
- import { readFileSync, writeFileSync } from 'node:fs';
2
- import { topicParts, type TopicPart } from '@erudit-js/core/content/topic';
3
- import { $CONTENT } from './singleton';
4
-
5
- // Call singleton to trigger initialization
6
- $CONTENT;
7
-
8
- let initialBuild = true;
9
-
10
- const contentRoot = () => ERUDIT.paths.project('content');
11
-
12
- export async function buildGlobalContent() {
13
- ERUDIT.log.debug.start('Building global content...');
14
-
15
- const isInitial = initialBuild;
16
- initialBuild = false;
17
-
18
- if (!isInitial && !hasContentChanges()) {
19
- ERUDIT.log.info('Skipping global content — nothing changed.');
20
- return;
21
- }
22
-
23
- const linkObject = await buildLinkObject();
24
-
25
- const linkTypes = linkObjectToTypes(linkObject);
26
- writeFileSync(
27
- ERUDIT.paths.project('.erudit/types/content.d.ts'),
28
- linkTypes,
29
- 'utf-8',
30
- );
31
-
32
- ERUDIT.log.success(
33
- isInitial ? 'Global content build complete!' : 'Global content updated!',
34
- );
35
- }
36
-
37
- function hasContentChanges() {
38
- for (const file of (ERUDIT.changedFiles || new Set<string>()).values()) {
39
- if (file.startsWith(`${contentRoot()}/`)) {
40
- return true;
41
- }
42
- }
43
-
44
- return false;
45
- }
46
-
47
- function linkObjectToTypes(linkObject: any): string {
48
- const indent = (level: number) => ' '.repeat(level);
49
-
50
- function toCamelCase(str: string): string {
51
- return str.replace(/[-_](.)/g, (_, char) => char.toUpperCase());
52
- }
53
-
54
- function processObject(obj: any, level: number): string {
55
- const lines: string[] = [];
56
-
57
- for (const [key, value] of Object.entries(obj) as [string, any][]) {
58
- if (key === '__jsdoc' || key === '__typeguard') continue;
59
-
60
- const camelKey = toCamelCase(key);
61
-
62
- // Add JSDoc comment if present
63
- if (value && typeof value === 'object' && value.__jsdoc) {
64
- const jsdocLines = value.__jsdoc.split('\n');
65
- jsdocLines.forEach((line: string) => {
66
- lines.push(indent(level) + line);
67
- });
68
- }
69
-
70
- // Determine if value has nested properties (excluding __jsdoc and __typeguard)
71
- const hasNestedProps =
72
- value &&
73
- typeof value === 'object' &&
74
- Object.keys(value).some((k) => k !== '__jsdoc' && k !== '__typeguard');
75
-
76
- // Get the typeguard from the object, default to GlobalContentItemTypeguard
77
- const typeguard = value?.__typeguard || 'GlobalContentItemTypeguard';
78
-
79
- if (hasNestedProps) {
80
- lines.push(indent(level) + `${camelKey}: ${typeguard} & {`);
81
- lines.push(processObject(value, level + 1));
82
- lines.push(indent(level) + `}`);
83
- } else {
84
- lines.push(indent(level) + `${camelKey}: ${typeguard} & {}`);
85
- }
86
- }
87
-
88
- return lines.join('\n');
89
- }
90
-
91
- const body = processObject(linkObject, 2);
92
-
93
- return `import type {
94
- GlobalContentItemTypeguard,
95
- GlobalContentTopicPartTypeguard,
96
- GlobalContentUniqueTypeguard,
97
- } from '@erudit-js/core/content/global';
98
-
99
- export {};
100
-
101
- declare global {
102
- const $CONTENT: {
103
- ${body}
104
- }
105
- }`;
106
- }
107
-
108
- /**
109
- * Loop through the content navigation tree and build a nested object representing the link structure:
110
- */
111
- async function buildLinkObject() {
112
- const linkTree: any = {};
113
-
114
- await ERUDIT.contentNav.walk((navItem) => {
115
- // Navigate to the correct position in the tree based on the full path
116
- let cursor = linkTree;
117
- const pathParts = navItem.fullId.split('/');
118
-
119
- // Navigate through parent parts
120
- for (let i = 0; i < pathParts.length - 1; i++) {
121
- cursor = cursor[pathParts[i]];
122
- }
123
-
124
- //
125
- //
126
- //
127
-
128
- if (navItem.type === 'page') {
129
- const pathToFile = ERUDIT.paths.project(
130
- `content/${navItem.contentRelPath}/${navItem.type}.tsx`,
131
- );
132
- const moduleContent = readFileSync(pathToFile, 'utf-8');
133
- const title = tryGetTitle(moduleContent);
134
-
135
- const jsdoc = jsdocLines([
136
- title ? `Title: ${title}` : undefined,
137
- `Type: ${navItem.type}`,
138
- `Location: [${navItem.contentRelPath}](file:///${pathToFile})`,
139
- ]);
140
-
141
- cursor[navItem.idPart] = {
142
- __typeguard: 'GlobalContentItemTypeguard',
143
- __jsdoc: `
144
- /**
145
- ${jsdoc}
146
- */
147
- `.trim(),
148
- ...tryGetUniquesObject(
149
- moduleContent,
150
- pathToFile,
151
- navItem.contentRelPath,
152
- ),
153
- };
154
- } else if (navItem.type === 'topic') {
155
- const pathToTopicFile = ERUDIT.paths.project(
156
- `content/${navItem.contentRelPath}/topic.ts`,
157
- );
158
- const topicModuleContent = readFileSync(pathToTopicFile, 'utf-8');
159
- const title = tryGetTitle(topicModuleContent);
160
-
161
- const jsdoc = jsdocLines([
162
- title ? `Title: ${title}` : undefined,
163
- `Type: topic`,
164
- `Location: [${navItem.contentRelPath}](file:///${pathToTopicFile})`,
165
- ]);
166
-
167
- cursor[navItem.idPart] = {
168
- __typeguard: 'GlobalContentItemTypeguard',
169
- __jsdoc: `
170
- /**
171
- ${jsdoc}
172
- */
173
- `.trim(),
174
- };
175
-
176
- for (const part of topicParts) {
177
- try {
178
- const pathToFile = ERUDIT.paths.project(
179
- `content/${navItem.contentRelPath}/${part}.tsx`,
180
- );
181
- const partContent = readFileSync(pathToFile, 'utf-8');
182
-
183
- const jsdoc = jsdocLines([
184
- title ? `Title: ${title}` : undefined,
185
- `Type: topic`,
186
- `Part: ${part}`,
187
- `Location: [${navItem.contentRelPath}](file:///${pathToFile})`,
188
- ]);
189
-
190
- cursor[navItem.idPart][part as TopicPart] = {
191
- __typeguard: 'GlobalContentTopicPartTypeguard',
192
- __jsdoc: `
193
- /**
194
- ${jsdoc}
195
- */
196
- `.trim(),
197
- ...tryGetUniquesObject(
198
- partContent,
199
- pathToFile,
200
- navItem.contentRelPath,
201
- ),
202
- };
203
- } catch {}
204
- }
205
- } else {
206
- const pathToFile = ERUDIT.paths.project(
207
- `content/${navItem.contentRelPath}/${navItem.type}.ts`,
208
- );
209
- const moduleContent = readFileSync(pathToFile, 'utf-8');
210
- const title = tryGetTitle(moduleContent);
211
-
212
- const jsdoc = jsdocLines([
213
- title ? `Title: ${title}` : undefined,
214
- `Type: ${navItem.type}`,
215
- `Location: [${navItem.contentRelPath}](file:///${pathToFile})`,
216
- ]);
217
-
218
- cursor[navItem.idPart] = {
219
- __typeguard: 'GlobalContentItemTypeguard',
220
- __jsdoc: `
221
- /**
222
- ${jsdoc}
223
- */
224
- `.trim(),
225
- };
226
- }
227
- });
228
-
229
- return linkTree;
230
- }
231
-
232
- function tryGetTitle(moduleContent: string) {
233
- const titleMatch = moduleContent.match(/title:\s*['"`](.*?)['"`]/);
234
-
235
- if (titleMatch) {
236
- return titleMatch[1].trim();
237
- }
238
- }
239
-
240
- function jsdocLines(lines: any[]) {
241
- return lines
242
- .filter(Boolean)
243
- .map((line) => ` * * ${line}`)
244
- .join('\n');
245
- }
246
-
247
- function tryGetUniquesObject(
248
- moduleContent: string,
249
- pathToFile: string,
250
- pathInContent: string,
251
- ) {
252
- // Match uniques: { ... } object (single or multiline)
253
- const uniquesMatch = moduleContent.match(/uniques:\s*\{([^}]*)\}/s);
254
-
255
- if (!uniquesMatch) {
256
- return {};
257
- }
258
-
259
- const uniquesContent = uniquesMatch[1];
260
-
261
- // Parse key-value pairs from uniques object
262
- const lines = uniquesContent.split('\n');
263
- const result: any = {};
264
-
265
- for (const line of lines) {
266
- // Skip commented out lines
267
- if (line.trim().startsWith('//')) {
268
- continue;
269
- }
270
-
271
- // Skip uniques starting with underscore
272
- if (line.trim().startsWith('_')) {
273
- continue;
274
- }
275
-
276
- const pairMatch = line.match(/(\w+):\s*(\w+)/);
277
- if (!pairMatch) {
278
- continue;
279
- }
280
-
281
- const [, uniqueName, tagName] = pairMatch;
282
-
283
- const jsdoc = jsdocLines([
284
- 'Unique',
285
- `Tag: \`<${tagName}>\``,
286
- `Location: [${pathInContent}](file:///${pathToFile})`,
287
- ]);
288
-
289
- result[`$${uniqueName}`] = {
290
- __typeguard: 'GlobalContentUniqueTypeguard',
291
- __jsdoc: `
292
- /**
293
- ${jsdoc}
294
- */
295
- `.trim(),
296
- };
297
- }
298
-
299
- return result;
300
- }
1
+ import { readFileSync, writeFileSync } from 'node:fs';
2
+ import { topicParts, type TopicPart } from '@erudit-js/core/content/topic';
3
+ import { $CONTENT } from './singleton';
4
+
5
+ // Call singleton to trigger initialization
6
+ $CONTENT;
7
+
8
+ let initialBuild = true;
9
+
10
+ const contentRoot = () => ERUDIT.paths.project('content');
11
+
12
+ export async function buildGlobalContent() {
13
+ ERUDIT.log.debug.start('Building global content...');
14
+
15
+ const isInitial = initialBuild;
16
+ initialBuild = false;
17
+
18
+ if (!isInitial && !hasContentChanges()) {
19
+ ERUDIT.log.info('Skipping global content — nothing changed.');
20
+ return;
21
+ }
22
+
23
+ const linkObject = await buildLinkObject();
24
+
25
+ const linkTypes = linkObjectToTypes(linkObject);
26
+ writeFileSync(
27
+ ERUDIT.paths.project('.erudit/types/content.d.ts'),
28
+ linkTypes,
29
+ 'utf-8',
30
+ );
31
+
32
+ ERUDIT.log.success(
33
+ isInitial ? 'Global content build complete!' : 'Global content updated!',
34
+ );
35
+ }
36
+
37
+ function hasContentChanges() {
38
+ for (const file of (ERUDIT.changedFiles || new Set<string>()).values()) {
39
+ if (file.startsWith(`${contentRoot()}/`)) {
40
+ return true;
41
+ }
42
+ }
43
+
44
+ return false;
45
+ }
46
+
47
+ function linkObjectToTypes(linkObject: any): string {
48
+ const indent = (level: number) => ' '.repeat(level);
49
+
50
+ function toCamelCase(str: string): string {
51
+ return str.replace(/[-_](.)/g, (_, char) => char.toUpperCase());
52
+ }
53
+
54
+ function processObject(obj: any, level: number): string {
55
+ const lines: string[] = [];
56
+
57
+ for (const [key, value] of Object.entries(obj) as [string, any][]) {
58
+ if (key === '__jsdoc' || key === '__typeguard') continue;
59
+
60
+ const camelKey = toCamelCase(key);
61
+
62
+ // Add JSDoc comment if present
63
+ if (value && typeof value === 'object' && value.__jsdoc) {
64
+ const jsdocLines = value.__jsdoc.split('\n');
65
+ jsdocLines.forEach((line: string) => {
66
+ lines.push(indent(level) + line);
67
+ });
68
+ }
69
+
70
+ // Determine if value has nested properties (excluding __jsdoc and __typeguard)
71
+ const hasNestedProps =
72
+ value &&
73
+ typeof value === 'object' &&
74
+ Object.keys(value).some((k) => k !== '__jsdoc' && k !== '__typeguard');
75
+
76
+ // Get the typeguard from the object, default to GlobalContentItemTypeguard
77
+ const typeguard = value?.__typeguard || 'GlobalContentItemTypeguard';
78
+
79
+ if (hasNestedProps) {
80
+ lines.push(indent(level) + `${camelKey}: ${typeguard} & {`);
81
+ lines.push(processObject(value, level + 1));
82
+ lines.push(indent(level) + `}`);
83
+ } else {
84
+ lines.push(indent(level) + `${camelKey}: ${typeguard} & {}`);
85
+ }
86
+ }
87
+
88
+ return lines.join('\n');
89
+ }
90
+
91
+ const body = processObject(linkObject, 2);
92
+
93
+ return `import type {
94
+ GlobalContentItemTypeguard,
95
+ GlobalContentTopicPartTypeguard,
96
+ GlobalContentUniqueTypeguard,
97
+ } from '@erudit-js/core/content/global';
98
+
99
+ export {};
100
+
101
+ declare global {
102
+ const $CONTENT: {
103
+ ${body}
104
+ }
105
+ }`;
106
+ }
107
+
108
+ /**
109
+ * Loop through the content navigation tree and build a nested object representing the link structure:
110
+ */
111
+ async function buildLinkObject() {
112
+ const linkTree: any = {};
113
+
114
+ await ERUDIT.contentNav.walk((navItem) => {
115
+ // Navigate to the correct position in the tree based on the full path
116
+ let cursor = linkTree;
117
+ const pathParts = navItem.fullId.split('/');
118
+
119
+ // Navigate through parent parts
120
+ for (let i = 0; i < pathParts.length - 1; i++) {
121
+ cursor = cursor[pathParts[i]];
122
+ }
123
+
124
+ //
125
+ //
126
+ //
127
+
128
+ if (navItem.type === 'page') {
129
+ const pathToFile = ERUDIT.paths.project(
130
+ `content/${navItem.contentRelPath}/${navItem.type}.tsx`,
131
+ );
132
+ const moduleContent = readFileSync(pathToFile, 'utf-8');
133
+ const title = tryGetTitle(moduleContent);
134
+
135
+ const jsdoc = jsdocLines([
136
+ title ? `Title: ${title}` : undefined,
137
+ `Type: ${navItem.type}`,
138
+ `Location: [${navItem.contentRelPath}](file:///${pathToFile})`,
139
+ ]);
140
+
141
+ cursor[navItem.idPart] = {
142
+ __typeguard: 'GlobalContentItemTypeguard',
143
+ __jsdoc: `
144
+ /**
145
+ ${jsdoc}
146
+ */
147
+ `.trim(),
148
+ ...tryGetUniquesObject(
149
+ moduleContent,
150
+ pathToFile,
151
+ navItem.contentRelPath,
152
+ ),
153
+ };
154
+ } else if (navItem.type === 'topic') {
155
+ const pathToTopicFile = ERUDIT.paths.project(
156
+ `content/${navItem.contentRelPath}/topic.ts`,
157
+ );
158
+ const topicModuleContent = readFileSync(pathToTopicFile, 'utf-8');
159
+ const title = tryGetTitle(topicModuleContent);
160
+
161
+ const jsdoc = jsdocLines([
162
+ title ? `Title: ${title}` : undefined,
163
+ `Type: topic`,
164
+ `Location: [${navItem.contentRelPath}](file:///${pathToTopicFile})`,
165
+ ]);
166
+
167
+ cursor[navItem.idPart] = {
168
+ __typeguard: 'GlobalContentItemTypeguard',
169
+ __jsdoc: `
170
+ /**
171
+ ${jsdoc}
172
+ */
173
+ `.trim(),
174
+ };
175
+
176
+ for (const part of topicParts) {
177
+ try {
178
+ const pathToFile = ERUDIT.paths.project(
179
+ `content/${navItem.contentRelPath}/${part}.tsx`,
180
+ );
181
+ const partContent = readFileSync(pathToFile, 'utf-8');
182
+
183
+ const jsdoc = jsdocLines([
184
+ title ? `Title: ${title}` : undefined,
185
+ `Type: topic`,
186
+ `Part: ${part}`,
187
+ `Location: [${navItem.contentRelPath}](file:///${pathToFile})`,
188
+ ]);
189
+
190
+ cursor[navItem.idPart][part as TopicPart] = {
191
+ __typeguard: 'GlobalContentTopicPartTypeguard',
192
+ __jsdoc: `
193
+ /**
194
+ ${jsdoc}
195
+ */
196
+ `.trim(),
197
+ ...tryGetUniquesObject(
198
+ partContent,
199
+ pathToFile,
200
+ navItem.contentRelPath,
201
+ ),
202
+ };
203
+ } catch {}
204
+ }
205
+ } else {
206
+ const pathToFile = ERUDIT.paths.project(
207
+ `content/${navItem.contentRelPath}/${navItem.type}.ts`,
208
+ );
209
+ const moduleContent = readFileSync(pathToFile, 'utf-8');
210
+ const title = tryGetTitle(moduleContent);
211
+
212
+ const jsdoc = jsdocLines([
213
+ title ? `Title: ${title}` : undefined,
214
+ `Type: ${navItem.type}`,
215
+ `Location: [${navItem.contentRelPath}](file:///${pathToFile})`,
216
+ ]);
217
+
218
+ cursor[navItem.idPart] = {
219
+ __typeguard: 'GlobalContentItemTypeguard',
220
+ __jsdoc: `
221
+ /**
222
+ ${jsdoc}
223
+ */
224
+ `.trim(),
225
+ };
226
+ }
227
+ });
228
+
229
+ return linkTree;
230
+ }
231
+
232
+ function tryGetTitle(moduleContent: string) {
233
+ const titleMatch = moduleContent.match(/title:\s*['"`](.*?)['"`]/);
234
+
235
+ if (titleMatch) {
236
+ return titleMatch[1].trim();
237
+ }
238
+ }
239
+
240
+ function jsdocLines(lines: any[]) {
241
+ return lines
242
+ .filter(Boolean)
243
+ .map((line) => ` * * ${line}`)
244
+ .join('\n');
245
+ }
246
+
247
+ function tryGetUniquesObject(
248
+ moduleContent: string,
249
+ pathToFile: string,
250
+ pathInContent: string,
251
+ ) {
252
+ // Match uniques: { ... } object (single or multiline)
253
+ const uniquesMatch = moduleContent.match(/uniques:\s*\{([^}]*)\}/s);
254
+
255
+ if (!uniquesMatch) {
256
+ return {};
257
+ }
258
+
259
+ const uniquesContent = uniquesMatch[1];
260
+
261
+ // Parse key-value pairs from uniques object
262
+ const lines = uniquesContent.split('\n');
263
+ const result: any = {};
264
+
265
+ for (const line of lines) {
266
+ // Skip commented out lines
267
+ if (line.trim().startsWith('//')) {
268
+ continue;
269
+ }
270
+
271
+ // Skip uniques starting with underscore
272
+ if (line.trim().startsWith('_')) {
273
+ continue;
274
+ }
275
+
276
+ const pairMatch = line.match(/(\w+):\s*(\w+)/);
277
+ if (!pairMatch) {
278
+ continue;
279
+ }
280
+
281
+ const [, uniqueName, tagName] = pairMatch;
282
+
283
+ const jsdoc = jsdocLines([
284
+ 'Unique',
285
+ `Tag: \`<${tagName}>\``,
286
+ `Location: [${pathInContent}](file:///${pathToFile})`,
287
+ ]);
288
+
289
+ result[`$${uniqueName}`] = {
290
+ __typeguard: 'GlobalContentUniqueTypeguard',
291
+ __jsdoc: `
292
+ /**
293
+ ${jsdoc}
294
+ */
295
+ `.trim(),
296
+ };
297
+ }
298
+
299
+ return result;
300
+ }
@@ -1,5 +1,5 @@
1
- import { createGlobalContentProxy } from '@erudit-js/core/content/global';
2
-
3
- export const $CONTENT = createGlobalContentProxy();
4
-
5
- (globalThis as any).$CONTENT = $CONTENT;
1
+ import { createGlobalContentProxy } from '@erudit-js/core/content/global';
2
+
3
+ export const $CONTENT = createGlobalContentProxy();
4
+
5
+ (globalThis as any).$CONTENT = $CONTENT;