@rynt/sdk 0.9.53

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 (332) hide show
  1. package/README.md +122 -0
  2. package/REGISTRIES.md +189 -0
  3. package/env.d.ts +11 -0
  4. package/host-shims.d.ts +30 -0
  5. package/package.json +88 -0
  6. package/src/extension-marketplace/api-types.ts +141 -0
  7. package/src/extension-marketplace/client.ts +296 -0
  8. package/src/extension-marketplace/index.ts +22 -0
  9. package/src/extension-marketplace/schemas.ts +178 -0
  10. package/src/extensions/ExtensionRoutePage.vue +17 -0
  11. package/src/extensions/context.ts +37 -0
  12. package/src/extensions/disabled-folder.ts +21 -0
  13. package/src/extensions/extension-expose-map.ts +5 -0
  14. package/src/extensions/extension-expose.ts +48 -0
  15. package/src/extensions/graph.ts +67 -0
  16. package/src/extensions/index.ts +251 -0
  17. package/src/extensions/invite-handler/types.ts +20 -0
  18. package/src/extensions/launcher-entities/create-launcher-entity.ts +25 -0
  19. package/src/extensions/launcher-entities/keys.ts +46 -0
  20. package/src/extensions/launcher-entities/launcher-entity-components.ts +177 -0
  21. package/src/extensions/launcher-entities/props-map.ts +69 -0
  22. package/src/extensions/launcher-entities/registry.ts +32 -0
  23. package/src/extensions/launcher-models/apis/accounts-contracts.ts +102 -0
  24. package/src/extensions/launcher-models/apis/launcher-model-apis.ts +553 -0
  25. package/src/extensions/launcher-models/keys.ts +23 -0
  26. package/src/extensions/launcher-models/public.ts +9 -0
  27. package/src/extensions/launcher-models/registry-core.ts +34 -0
  28. package/src/extensions/manifest-types.ts +22 -0
  29. package/src/extensions/manifest.ts +46 -0
  30. package/src/extensions/marketplace-open-key.ts +26 -0
  31. package/src/extensions/plugin-types.ts +44 -0
  32. package/src/extensions/plugin.ts +62 -0
  33. package/src/extensions/registries/bootstrap.ts +11 -0
  34. package/src/extensions/registries/builtins/account-provider.ts +6 -0
  35. package/src/extensions/registries/builtins/app-topbar-left-widgets.ts +6 -0
  36. package/src/extensions/registries/builtins/app-topbar-right-widgets.ts +6 -0
  37. package/src/extensions/registries/builtins/app-topbar-status-widgets.ts +6 -0
  38. package/src/extensions/registries/builtins/build-card-actions.ts +6 -0
  39. package/src/extensions/registries/builtins/build-card-after-meta.ts +6 -0
  40. package/src/extensions/registries/builtins/build-card-before-media.ts +6 -0
  41. package/src/extensions/registries/builtins/build-card-before-meta.ts +6 -0
  42. package/src/extensions/registries/builtins/build-card-footer-actions.ts +6 -0
  43. package/src/extensions/registries/builtins/build-detail-after-content.ts +6 -0
  44. package/src/extensions/registries/builtins/build-detail-before-content.ts +6 -0
  45. package/src/extensions/registries/builtins/build-detail-before-hero.ts +6 -0
  46. package/src/extensions/registries/builtins/build-detail-header-actions.ts +6 -0
  47. package/src/extensions/registries/builtins/build-detail-mod-row-actions.ts +6 -0
  48. package/src/extensions/registries/builtins/build-detail-resourcepack-row-actions.ts +6 -0
  49. package/src/extensions/registries/builtins/build-detail-right-column-bottom.ts +6 -0
  50. package/src/extensions/registries/builtins/build-detail-right-column-top.ts +6 -0
  51. package/src/extensions/registries/builtins/dialog-footer-actions.ts +6 -0
  52. package/src/extensions/registries/builtins/feed-after-content.ts +6 -0
  53. package/src/extensions/registries/builtins/feed-before-content.ts +6 -0
  54. package/src/extensions/registries/builtins/file-editor.ts +19 -0
  55. package/src/extensions/registries/builtins/friends-after-list.ts +6 -0
  56. package/src/extensions/registries/builtins/friends-before-list.ts +6 -0
  57. package/src/extensions/registries/builtins/index.ts +141 -0
  58. package/src/extensions/registries/builtins/invite-handler.ts +7 -0
  59. package/src/extensions/registries/builtins/library-after-content.ts +6 -0
  60. package/src/extensions/registries/builtins/library-before-content.ts +6 -0
  61. package/src/extensions/registries/builtins/loader.ts +8 -0
  62. package/src/extensions/registries/builtins/map-card-actions.ts +6 -0
  63. package/src/extensions/registries/builtins/map-card-after-meta.ts +6 -0
  64. package/src/extensions/registries/builtins/map-card-before-meta.ts +6 -0
  65. package/src/extensions/registries/builtins/map-card-footer-actions.ts +6 -0
  66. package/src/extensions/registries/builtins/map-detail-after-content.ts +6 -0
  67. package/src/extensions/registries/builtins/map-detail-before-content.ts +6 -0
  68. package/src/extensions/registries/builtins/map-detail-header-actions.ts +6 -0
  69. package/src/extensions/registries/builtins/markdown-editor-tiptap-extensions.ts +7 -0
  70. package/src/extensions/registries/builtins/markdown-editor-toolbar-actions.ts +6 -0
  71. package/src/extensions/registries/builtins/markdown-renderer-after-content.ts +6 -0
  72. package/src/extensions/registries/builtins/markdown-renderer-before-content.ts +6 -0
  73. package/src/extensions/registries/builtins/mod-details-footer-actions.ts +6 -0
  74. package/src/extensions/registries/builtins/mod-manage-actions.ts +6 -0
  75. package/src/extensions/registries/builtins/mod-provider.ts +5 -0
  76. package/src/extensions/registries/builtins/nav.ts +7 -0
  77. package/src/extensions/registries/builtins/page.ts +13 -0
  78. package/src/extensions/registries/builtins/projects-after-content.ts +6 -0
  79. package/src/extensions/registries/builtins/projects-before-content.ts +6 -0
  80. package/src/extensions/registries/builtins/resourcepack-manage-actions.ts +7 -0
  81. package/src/extensions/registries/builtins/server-card-actions.ts +6 -0
  82. package/src/extensions/registries/builtins/server-card-after-meta.ts +6 -0
  83. package/src/extensions/registries/builtins/server-card-before-meta.ts +6 -0
  84. package/src/extensions/registries/builtins/server-card-footer-actions.ts +6 -0
  85. package/src/extensions/registries/builtins/server-detail-after-content.ts +6 -0
  86. package/src/extensions/registries/builtins/server-detail-before-content.ts +6 -0
  87. package/src/extensions/registries/builtins/server-detail-header-actions.ts +6 -0
  88. package/src/extensions/registries/builtins/settings-after-sections.ts +6 -0
  89. package/src/extensions/registries/builtins/settings-before-sections.ts +6 -0
  90. package/src/extensions/registries/builtins/settings-section-widgets.ts +6 -0
  91. package/src/extensions/registries/builtins/shaderpack-manage-actions.ts +7 -0
  92. package/src/extensions/registries/builtins/shell.ts +5 -0
  93. package/src/extensions/registries/builtins/sidebar-after-content.ts +6 -0
  94. package/src/extensions/registries/builtins/sidebar-before-content.ts +6 -0
  95. package/src/extensions/registries/builtins/sidebar-footer-widgets.ts +6 -0
  96. package/src/extensions/registries/builtins/sidebar-header-widgets.ts +6 -0
  97. package/src/extensions/registries/builtins/sidebar.ts +11 -0
  98. package/src/extensions/registries/builtins/theme.ts +5 -0
  99. package/src/extensions/registries/builtins/user-card-after-meta.ts +6 -0
  100. package/src/extensions/registries/builtins/user-card-before-meta.ts +6 -0
  101. package/src/extensions/registries/builtins/user-menu-actions.ts +6 -0
  102. package/src/extensions/registries/builtins/user-menu-after-actions.ts +6 -0
  103. package/src/extensions/registries/builtins/user-menu-before-actions.ts +6 -0
  104. package/src/extensions/registries/builtins/user-strip.ts +5 -0
  105. package/src/extensions/registries/clear-extension-ui-registries.ts +15 -0
  106. package/src/extensions/registries/define-extension-registry.ts +58 -0
  107. package/src/extensions/registries/extension-host-api.ts +41 -0
  108. package/src/extensions/registries/extension-registry-api.ts +103 -0
  109. package/src/extensions/registries/extension-registry-payload-map.ts +9 -0
  110. package/src/extensions/registries/extension-scope.ts +41 -0
  111. package/src/extensions/registries/get-registry.ts +23 -0
  112. package/src/extensions/registries/index.ts +58 -0
  113. package/src/extensions/registries/manifest-rynt.ts +193 -0
  114. package/src/extensions/registries/registry-slot.ts +40 -0
  115. package/src/extensions/registries/registry-value-map.ts +89 -0
  116. package/src/extensions/registries/store.ts +206 -0
  117. package/src/extensions/resolve-extensions.ts +245 -0
  118. package/src/extensions/router-bridge.ts +103 -0
  119. package/src/extensions/session.ts +6 -0
  120. package/src/extensions/slug.ts +23 -0
  121. package/src/extensions/version.ts +147 -0
  122. package/src/host/extensions-composables.ts +33 -0
  123. package/src/host/extensions-init.ts +194 -0
  124. package/src/host/index.ts +11 -0
  125. package/src/host/launcher-models/index.ts +4 -0
  126. package/src/index.ts +229 -0
  127. package/src/minecraft-loader/base-loader.ts +102 -0
  128. package/src/minecraft-loader/index.ts +11 -0
  129. package/src/minecraft-loader/loader-registry.ts +72 -0
  130. package/src/shared/api/assets.ts +112 -0
  131. package/src/shared/api/auth.ts +283 -0
  132. package/src/shared/api/builds.ts +647 -0
  133. package/src/shared/api/config.ts +19 -0
  134. package/src/shared/api/download-stats.ts +103 -0
  135. package/src/shared/api/downloads.ts +36 -0
  136. package/src/shared/api/entity-authorship.ts +60 -0
  137. package/src/shared/api/events.ts +393 -0
  138. package/src/shared/api/friends.ts +140 -0
  139. package/src/shared/api/graphql.ts +87 -0
  140. package/src/shared/api/index.ts +23 -0
  141. package/src/shared/api/invites.ts +262 -0
  142. package/src/shared/api/library.ts +44 -0
  143. package/src/shared/api/maps.ts +385 -0
  144. package/src/shared/api/notify-websocket.ts +140 -0
  145. package/src/shared/api/posts.ts +357 -0
  146. package/src/shared/api/projectServers.ts +379 -0
  147. package/src/shared/api/serverMembers.ts +173 -0
  148. package/src/shared/api/users.ts +294 -0
  149. package/src/shared/composables/buildEditor/useBuildEditor.ts +66 -0
  150. package/src/shared/composables/buildManifest/buildManifest.ts +447 -0
  151. package/src/shared/composables/filesEditor/filesEditor.ts +346 -0
  152. package/src/shared/composables/index.ts +10 -0
  153. package/src/shared/composables/modsEditor/modsEditor.ts +1678 -0
  154. package/src/shared/composables/registrySlot/registry-slot-utils.ts +25 -0
  155. package/src/shared/composables/registrySlot/useRegistrySlotMissing.ts +35 -0
  156. package/src/shared/composables/resourcePacksEditor/resourcePacksEditor.ts +448 -0
  157. package/src/shared/composables/shaderPacksEditor/shaderPacksEditor.ts +395 -0
  158. package/src/shared/composables/useSkinRender.ts +70 -0
  159. package/src/shared/composables/useZlDeepLink.ts +178 -0
  160. package/src/shared/definitions/defineGraphCache.ts +216 -0
  161. package/src/shared/definitions/defineStore.ts +32 -0
  162. package/src/shared/definitions/index.ts +2 -0
  163. package/src/shared/minecraft-types/build-manifest.ts +611 -0
  164. package/src/shared/minecraft-types/index.ts +3 -0
  165. package/src/shared/minecraft-types/launcher-versions.ts +32 -0
  166. package/src/shared/minecraft-types/minecraft-launcher-types.ts +276 -0
  167. package/src/shared/mocks/index.ts +1 -0
  168. package/src/shared/mocks/navigation.ts +17 -0
  169. package/src/shared/mods/http.ts +45 -0
  170. package/src/shared/mods/index.ts +5 -0
  171. package/src/shared/mods/marketplace-editor-search.ts +266 -0
  172. package/src/shared/mods/marketplace-search-utils.ts +42 -0
  173. package/src/shared/mods/mod-marketplace-registry.ts +66 -0
  174. package/src/shared/mods/mod-marketplace-types.ts +28 -0
  175. package/src/shared/mods/providers/curseforge.ts +464 -0
  176. package/src/shared/mods/providers/index.ts +8 -0
  177. package/src/shared/mods/providers/modrinth.ts +402 -0
  178. package/src/shared/mods/resolve-mods-provider-loader-ids.ts +77 -0
  179. package/src/shared/mods/types.ts +76 -0
  180. package/src/shared/styles/index.css +713 -0
  181. package/src/shared/themes/index.ts +23 -0
  182. package/src/shared/themes/theme-tokens-black.json +126 -0
  183. package/src/shared/themes/theme-tokens-classic.json +126 -0
  184. package/src/shared/themes/theme-tokens-pink.json +126 -0
  185. package/src/shared/themes/theme-tokens.json +126 -0
  186. package/src/shared/themes/types.ts +85 -0
  187. package/src/shared/types/API_DOCUMENTATION.md +422 -0
  188. package/src/shared/types/account.ts +40 -0
  189. package/src/shared/types/build.ts +8 -0
  190. package/src/shared/types/entities.ts +181 -0
  191. package/src/shared/types/index.ts +6 -0
  192. package/src/shared/types/invite-payloads.ts +60 -0
  193. package/src/shared/types/navigation.ts +16 -0
  194. package/src/shared/types/running-build.ts +51 -0
  195. package/src/shared/types/serverMember.ts +17 -0
  196. package/src/shared/types/user.ts +55 -0
  197. package/src/shared/ui/base/Avatar.vue +262 -0
  198. package/src/shared/ui/base/Badge.vue +47 -0
  199. package/src/shared/ui/base/Button.vue +78 -0
  200. package/src/shared/ui/base/Divider.vue +42 -0
  201. package/src/shared/ui/base/Icon.vue +597 -0
  202. package/src/shared/ui/base/StatusIndicator.vue +44 -0
  203. package/src/shared/ui/base/index.ts +7 -0
  204. package/src/shared/ui/cards/InviteCard.vue +47 -0
  205. package/src/shared/ui/cards/index.ts +2 -0
  206. package/src/shared/ui/dialog/Dialog.vue +71 -0
  207. package/src/shared/ui/dialog/DialogContent.vue +31 -0
  208. package/src/shared/ui/dialog/DialogFooter.vue +14 -0
  209. package/src/shared/ui/dialog/DialogHeader.vue +41 -0
  210. package/src/shared/ui/dialog/index.ts +5 -0
  211. package/src/shared/ui/editors/AttachmentImagesEditor.vue +133 -0
  212. package/src/shared/ui/editors/ContentAttachmentsDisplay.vue +76 -0
  213. package/src/shared/ui/editors/MarkdownEditor.vue +956 -0
  214. package/src/shared/ui/editors/MarkdownRenderer.vue +299 -0
  215. package/src/shared/ui/editors/RichContentImageViewer.vue +85 -0
  216. package/src/shared/ui/editors/SocialPostMediaZone.vue +320 -0
  217. package/src/shared/ui/editors/index.ts +6 -0
  218. package/src/shared/ui/editors/markdown-editor-gallery.ts +234 -0
  219. package/src/shared/ui/editors/markdown-editor-image.ts +178 -0
  220. package/src/shared/ui/form/Checkbox.vue +38 -0
  221. package/src/shared/ui/form/FormField.vue +30 -0
  222. package/src/shared/ui/form/FormGrid.vue +38 -0
  223. package/src/shared/ui/form/ImageEditor.vue +598 -0
  224. package/src/shared/ui/form/Input.vue +72 -0
  225. package/src/shared/ui/form/Range.vue +65 -0
  226. package/src/shared/ui/form/Select.vue +76 -0
  227. package/src/shared/ui/form/Switch.vue +38 -0
  228. package/src/shared/ui/form/Textarea.vue +144 -0
  229. package/src/shared/ui/form/index.ts +9 -0
  230. package/src/shared/ui/index.ts +9 -0
  231. package/src/shared/ui/layout/BusyOverlay.vue +31 -0
  232. package/src/shared/ui/layout/Callout.vue +44 -0
  233. package/src/shared/ui/layout/Card.vue +38 -0
  234. package/src/shared/ui/layout/Container.vue +36 -0
  235. package/src/shared/ui/layout/EmptyState.vue +99 -0
  236. package/src/shared/ui/layout/EntityMediaRow.vue +54 -0
  237. package/src/shared/ui/layout/FilterResultsLayout.vue +22 -0
  238. package/src/shared/ui/layout/FloatingPanel.vue +37 -0
  239. package/src/shared/ui/layout/FullscreenDimmer.vue +11 -0
  240. package/src/shared/ui/layout/Grid.vue +40 -0
  241. package/src/shared/ui/layout/Inline.vue +59 -0
  242. package/src/shared/ui/layout/LoadingState.vue +39 -0
  243. package/src/shared/ui/layout/MediaBox.vue +47 -0
  244. package/src/shared/ui/layout/OverlayPanel.vue +28 -0
  245. package/src/shared/ui/layout/OverlayWaitPanel.vue +22 -0
  246. package/src/shared/ui/layout/PageSection.vue +43 -0
  247. package/src/shared/ui/layout/PageToolbar.vue +29 -0
  248. package/src/shared/ui/layout/Panel.vue +39 -0
  249. package/src/shared/ui/layout/ProgressBar.vue +49 -0
  250. package/src/shared/ui/layout/Section.vue +30 -0
  251. package/src/shared/ui/layout/SegmentedControl.vue +43 -0
  252. package/src/shared/ui/layout/SelectableCard.vue +46 -0
  253. package/src/shared/ui/layout/SelectableRow.vue +41 -0
  254. package/src/shared/ui/layout/Skeleton.vue +25 -0
  255. package/src/shared/ui/layout/SkeletonAvatar.vue +30 -0
  256. package/src/shared/ui/layout/SkeletonEntityCard.vue +20 -0
  257. package/src/shared/ui/layout/SkeletonFeedPost.vue +22 -0
  258. package/src/shared/ui/layout/SkeletonGrid.vue +18 -0
  259. package/src/shared/ui/layout/SkeletonListRow.vue +31 -0
  260. package/src/shared/ui/layout/SkeletonText.vue +25 -0
  261. package/src/shared/ui/layout/Stack.vue +42 -0
  262. package/src/shared/ui/layout/StateBlock.vue +44 -0
  263. package/src/shared/ui/layout/TwoPaneLayout.vue +35 -0
  264. package/src/shared/ui/layout/VirtualList.vue +160 -0
  265. package/src/shared/ui/layout/index.ts +35 -0
  266. package/src/shared/ui/layout/skeletonSurfaceStyles.ts +24 -0
  267. package/src/shared/ui/navigation/NavItem.vue +139 -0
  268. package/src/shared/ui/navigation/Tab.vue +61 -0
  269. package/src/shared/ui/navigation/Tabs.vue +37 -0
  270. package/src/shared/ui/navigation/index.ts +4 -0
  271. package/src/shared/ui/primitives/Action.vue +19 -0
  272. package/src/shared/ui/primitives/Block.vue +28 -0
  273. package/src/shared/ui/primitives/CanvasView.vue +19 -0
  274. package/src/shared/ui/primitives/Control.vue +24 -0
  275. package/src/shared/ui/primitives/ControlSelect.vue +19 -0
  276. package/src/shared/ui/primitives/ControlTextarea.vue +17 -0
  277. package/src/shared/ui/primitives/FieldLabel.vue +19 -0
  278. package/src/shared/ui/primitives/Form.vue +19 -0
  279. package/src/shared/ui/primitives/Heading.vue +29 -0
  280. package/src/shared/ui/primitives/Image.vue +17 -0
  281. package/src/shared/ui/primitives/LineBreak.vue +3 -0
  282. package/src/shared/ui/primitives/Link.vue +19 -0
  283. package/src/shared/ui/primitives/List.vue +28 -0
  284. package/src/shared/ui/primitives/ListItem.vue +19 -0
  285. package/src/shared/ui/primitives/OptionItem.vue +19 -0
  286. package/src/shared/ui/primitives/Text.vue +28 -0
  287. package/src/shared/ui/primitives/VideoView.vue +19 -0
  288. package/src/shared/ui/primitives/index.ts +19 -0
  289. package/src/shared/ui/primitives/resolveElement.ts +25 -0
  290. package/src/shared/ui/special/AngularAccent.vue +106 -0
  291. package/src/shared/ui/special/ExtensionRegistrySlotButton.vue +143 -0
  292. package/src/shared/ui/special/InfoRow.vue +39 -0
  293. package/src/shared/ui/special/LogViewer.vue +53 -0
  294. package/src/shared/ui/special/PageHeader.vue +23 -0
  295. package/src/shared/ui/special/RegistrySlotMissingCallout.vue +48 -0
  296. package/src/shared/ui/special/WelcomeCard.vue +32 -0
  297. package/src/shared/ui/special/index.ts +9 -0
  298. package/src/shared/utils/app-paths.ts +50 -0
  299. package/src/shared/utils/attachments.ts +16 -0
  300. package/src/shared/utils/autostart.ts +213 -0
  301. package/src/shared/utils/build-files.ts +439 -0
  302. package/src/shared/utils/build-manifest-init.ts +176 -0
  303. package/src/shared/utils/cloudinary.ts +67 -0
  304. package/src/shared/utils/cn.ts +7 -0
  305. package/src/shared/utils/download-stats-week.ts +165 -0
  306. package/src/shared/utils/entity-api-to-cache.ts +84 -0
  307. package/src/shared/utils/entity-build-from-api.ts +1 -0
  308. package/src/shared/utils/entity-display.ts +27 -0
  309. package/src/shared/utils/entity-map-from-api.ts +1 -0
  310. package/src/shared/utils/file-hash.ts +65 -0
  311. package/src/shared/utils/formatSize.ts +5 -0
  312. package/src/shared/utils/formatTime.ts +157 -0
  313. package/src/shared/utils/getAccountSkinRender.ts +32 -0
  314. package/src/shared/utils/index.ts +34 -0
  315. package/src/shared/utils/local-mods.ts +678 -0
  316. package/src/shared/utils/local-settings.ts +217 -0
  317. package/src/shared/utils/member-join-stats.ts +35 -0
  318. package/src/shared/utils/platform.ts +86 -0
  319. package/src/shared/utils/play-host-slug.ts +92 -0
  320. package/src/shared/utils/rich-content.ts +294 -0
  321. package/src/shared/utils/safeRequest.ts +23 -0
  322. package/src/shared/utils/semver.ts +81 -0
  323. package/src/shared/utils/serverPermissions.ts +155 -0
  324. package/src/shared/utils/skin-render-cache.ts +372 -0
  325. package/src/shared/utils/stripMarkdown.ts +45 -0
  326. package/src/shared/utils/transliterate.ts +74 -0
  327. package/src/shared/utils/updateAccountSkinRender.ts +64 -0
  328. package/src/shared/utils/updater.ts +218 -0
  329. package/src/shared/utils/uploadImage.ts +195 -0
  330. package/src/shared/utils/user-status.ts +9 -0
  331. package/src/tiptap/index.ts +7 -0
  332. package/tsconfig.json +13 -0
@@ -0,0 +1,402 @@
1
+ import type { Mod, ResourcePack, ShaderPack } from '../../minecraft-types/build-manifest';
2
+ import { httpGet } from '../http';
3
+ import type { ModMarketplaceProvider } from '../mod-marketplace-types';
4
+ import { getMarketplaceLoaderIds } from '../resolve-mods-provider-loader-ids';
5
+ import type {
6
+ InstallContext,
7
+ MarketplaceInstallVersion,
8
+ MarketplaceItem,
9
+ MarketplaceSearchContext,
10
+ MarketplaceSearchResult,
11
+ ProjectType,
12
+ ProjectDetails,
13
+ } from '../types';
14
+ import { MARKETPLACE_SEARCH_PAGE_SIZE } from '../types';
15
+ import { marked } from 'marked';
16
+
17
+ const MODRINTH_PROVIDER_ID = 'modrinth';
18
+
19
+ const MODRINTH_BASE = 'https://api.modrinth.com/v2';
20
+
21
+ type ModrinthSearchHit = {
22
+ project_id: string;
23
+ slug: string;
24
+ title: string;
25
+ description: string;
26
+ icon_url?: string;
27
+ downloads?: number;
28
+ };
29
+
30
+ type ModrinthSearchResponse = {
31
+ hits: ModrinthSearchHit[];
32
+ offset?: number;
33
+ limit?: number;
34
+ total_hits?: number;
35
+ };
36
+
37
+ type ModrinthVersionFile = {
38
+ url: string;
39
+ filename: string;
40
+ primary?: boolean;
41
+ size: number;
42
+ hashes: {
43
+ sha1?: string;
44
+ sha512?: string;
45
+ };
46
+ };
47
+
48
+ type ModrinthVersionDependency = {
49
+ dependency_type: 'required' | 'optional' | 'incompatible' | 'embedded';
50
+ project_id?: string;
51
+ };
52
+
53
+ type ModrinthProjectVersion = {
54
+ id: string;
55
+ version_number: string;
56
+ date_published?: string;
57
+ files: ModrinthVersionFile[];
58
+ dependencies?: ModrinthVersionDependency[];
59
+ };
60
+
61
+ function modrinthFacets(ctx: MarketplaceSearchContext): string {
62
+ const facets: string[][] = [];
63
+ const projectType = ctx.projectType === 'shaderpack' ? 'shader' : ctx.projectType;
64
+ facets.push([`project_type:${projectType}`]);
65
+ if (ctx.minecraftVersion) {
66
+ facets.push([`versions:${ctx.minecraftVersion}`]);
67
+ }
68
+ // Resource packs and shader packs don't depend on mod loader, so don't filter by loader
69
+ if (
70
+ ctx.projectType !== 'resourcepack' &&
71
+ ctx.projectType !== 'shaderpack'
72
+ ) {
73
+ const loaderIds = getMarketplaceLoaderIds(ctx, MODRINTH_PROVIDER_ID);
74
+ if (loaderIds.length) {
75
+ // OR-группа: fabric OR quilt OR forge...
76
+ facets.push(loaderIds.map((id) => `categories:${id}`));
77
+ }
78
+ }
79
+ return JSON.stringify(facets);
80
+ }
81
+
82
+ export async function modrinthSearch(
83
+ ctx: MarketplaceSearchContext,
84
+ ): Promise<MarketplaceSearchResult> {
85
+ const page = ctx.page ?? 0;
86
+ const limit = MARKETPLACE_SEARCH_PAGE_SIZE;
87
+ const offset = page * limit;
88
+
89
+ const data = await httpGet<ModrinthSearchResponse>(
90
+ `${MODRINTH_BASE}/search`,
91
+ {
92
+ params: {
93
+ query: ctx.query,
94
+ facets: modrinthFacets(ctx),
95
+ limit,
96
+ offset,
97
+ index: 'relevance',
98
+ },
99
+ },
100
+ );
101
+
102
+ const hits = data.hits ?? [];
103
+ const items = hits.map((h) => ({
104
+ provider: 'modrinth' as const,
105
+ projectType: ctx.projectType,
106
+ projectId: h.project_id,
107
+ slug: h.slug,
108
+ name: h.title,
109
+ summary: h.description,
110
+ iconUrl: h.icon_url,
111
+ downloads: h.downloads,
112
+ }));
113
+
114
+ const totalHits = data.total_hits;
115
+ const hasMore =
116
+ typeof totalHits === 'number'
117
+ ? offset + hits.length < totalHits
118
+ : hits.length === limit;
119
+
120
+ return { items, hasMore };
121
+ }
122
+
123
+ async function modrinthGetCompatibleVersions(
124
+ projectId: string,
125
+ ctx: InstallContext,
126
+ ): Promise<ModrinthProjectVersion[]> {
127
+ const params: Record<string, string> = {};
128
+ if (ctx.minecraftVersion)
129
+ params.game_versions = JSON.stringify([ctx.minecraftVersion]);
130
+ if (
131
+ ctx.projectType !== 'resourcepack' &&
132
+ ctx.projectType !== 'shaderpack'
133
+ ) {
134
+ const loaderIds = getMarketplaceLoaderIds(ctx, MODRINTH_PROVIDER_ID);
135
+ if (loaderIds.length) {
136
+ params.loaders = JSON.stringify(loaderIds);
137
+ }
138
+ }
139
+
140
+ const data = await httpGet<ModrinthProjectVersion[]>(
141
+ `${MODRINTH_BASE}/project/${encodeURIComponent(projectId)}/version`,
142
+ { params },
143
+ );
144
+ if (!data?.length) {
145
+ throw new Error('No compatible versions found on Modrinth');
146
+ }
147
+ return data;
148
+ }
149
+
150
+ function pickPrimaryFile(files: ModrinthVersionFile[]): ModrinthVersionFile {
151
+ const primary = files.find((f) => f.primary);
152
+ return primary ?? files[0];
153
+ }
154
+
155
+ /**
156
+ * Convert Modrinth dependencies to Mod dependencies
157
+ * Note: This function needs to fetch project details to get slug
158
+ * For now, we'll return dependencies with modId only, and fetch slug/version during install
159
+ */
160
+ async function toDependencies(
161
+ deps: ModrinthVersionDependency[] | undefined,
162
+ ctx: InstallContext,
163
+ ): Promise<Mod['dependencies']> {
164
+ if (!deps?.length) return [];
165
+
166
+ const result: Mod['dependencies'] = [];
167
+
168
+ for (const dep of deps) {
169
+ if (
170
+ !dep.project_id ||
171
+ (dep.dependency_type !== 'required' &&
172
+ dep.dependency_type !== 'incompatible')
173
+ ) {
174
+ continue;
175
+ }
176
+
177
+ try {
178
+ // Fetch project details to get slug
179
+ const projectDetails = await modrinthGetProjectDetails(dep.project_id);
180
+
181
+ result.push({
182
+ type: dep.dependency_type,
183
+ source: 'modrinth',
184
+ modId: dep.project_id,
185
+ slug: projectDetails.slug,
186
+ version: '', // Empty string means "any version" - Modrinth API doesn't provide version requirement
187
+ });
188
+ } catch (e) {
189
+ console.warn(
190
+ `[modrinth] Failed to get project details for dependency ${dep.project_id}:`,
191
+ e,
192
+ );
193
+ // Fallback: use project_id as slug
194
+ result.push({
195
+ type: dep.dependency_type,
196
+ source: 'modrinth',
197
+ modId: dep.project_id,
198
+ slug: dep.project_id,
199
+ version: '', // Empty string - don't use fallback version of the mod itself
200
+ });
201
+ }
202
+ }
203
+
204
+ return result;
205
+ }
206
+
207
+ export async function modrinthGetInstallVersions(
208
+ projectId: string,
209
+ ctx: InstallContext,
210
+ ): Promise<MarketplaceInstallVersion[]> {
211
+ const versions = await modrinthGetCompatibleVersions(projectId, ctx);
212
+ return versions.map((version, index) => ({
213
+ id: version.id,
214
+ label: version.version_number,
215
+ publishedAt: version.date_published,
216
+ recommended: index === 0,
217
+ }));
218
+ }
219
+
220
+ export async function modrinthInstallToManifestEntry(
221
+ item: MarketplaceItem,
222
+ ctx: InstallContext,
223
+ selectedVersionId?: string,
224
+ ): Promise<Mod | ResourcePack | ShaderPack> {
225
+ const versions = await modrinthGetCompatibleVersions(item.projectId, ctx);
226
+ const version = selectedVersionId
227
+ ? versions.find((v) => v.id === selectedVersionId)
228
+ : versions[0];
229
+ if (!version) {
230
+ throw new Error('Selected Modrinth version not found');
231
+ }
232
+ const file = pickPrimaryFile(version.files ?? []);
233
+ const sha1 = file?.hashes?.sha1;
234
+ if (!sha1) {
235
+ throw new Error('Modrinth file does not contain sha1 hash');
236
+ }
237
+
238
+ const fileEntry = {
239
+ type: 'primary' as const,
240
+ filename: file.filename,
241
+ path:
242
+ ctx.projectType === 'resourcepack'
243
+ ? `resourcepacks/${file.filename}`
244
+ : ctx.projectType === 'shaderpack'
245
+ ? `shaderpacks/${file.filename}`
246
+ : `mods/${file.filename}`,
247
+ size: file.size,
248
+ hashes: { sha1 },
249
+ urls: [file.url],
250
+ side: 'both' as const,
251
+ };
252
+
253
+ if (ctx.projectType === 'resourcepack') {
254
+ const rp: ResourcePack = {
255
+ source: 'modrinth',
256
+ id: item.projectId,
257
+ name: item.name,
258
+ projectSlug: item.slug,
259
+ version: version.version_number,
260
+ image: item.iconUrl,
261
+ constraints: {
262
+ minecraft: ctx.minecraftVersion,
263
+ },
264
+ files: [fileEntry],
265
+ };
266
+ return rp;
267
+ }
268
+
269
+ if (ctx.projectType === 'shaderpack') {
270
+ const sp: ShaderPack = {
271
+ source: 'modrinth',
272
+ id: item.projectId,
273
+ name: item.name,
274
+ projectSlug: item.slug,
275
+ version: version.version_number,
276
+ image: item.iconUrl,
277
+ constraints: {
278
+ minecraft: ctx.minecraftVersion,
279
+ },
280
+ files: [fileEntry],
281
+ };
282
+ return sp;
283
+ }
284
+
285
+ const mod: Mod = {
286
+ source: 'modrinth',
287
+ id: item.projectId, // Use projectId (provider-specific ID) for id
288
+ name: item.name,
289
+ projectSlug: item.slug, // Use slug for projectSlug
290
+ image: item.iconUrl,
291
+ version: version.version_number,
292
+ constraints: {
293
+ minecraft: ctx.minecraftVersion,
294
+ loader: ctx.loader,
295
+ },
296
+ files: [fileEntry],
297
+ dependencies: await toDependencies(version.dependencies, ctx),
298
+ };
299
+ return mod;
300
+ }
301
+
302
+ type ModrinthProject = {
303
+ id: string;
304
+ slug: string;
305
+ title: string;
306
+ description?: string;
307
+ body?: string;
308
+ icon_url?: string;
309
+ downloads?: number;
310
+ categories?: string[];
311
+ client_side?: 'required' | 'optional' | 'unsupported';
312
+ server_side?: 'required' | 'optional' | 'unsupported';
313
+ project_type: 'mod' | 'modpack' | 'resourcepack' | 'plugin' | 'shader';
314
+ author?: string;
315
+ team?: string;
316
+ published?: string;
317
+ updated?: string;
318
+ approved?: string;
319
+ status?: string;
320
+ license?: {
321
+ id?: string;
322
+ name?: string;
323
+ url?: string;
324
+ };
325
+ gallery?: Array<{ url?: string; featured?: boolean }>;
326
+ color?: number;
327
+ thread_id?: string;
328
+ monetization_status?: string;
329
+ project_id?: string;
330
+ follows?: number;
331
+ versions?: string[];
332
+ };
333
+
334
+ export async function modrinthGetProjectDetails(
335
+ projectIdOrSlug: string,
336
+ ): Promise<ProjectDetails> {
337
+ const data = await httpGet<ModrinthProject>(
338
+ `${MODRINTH_BASE}/project/${encodeURIComponent(projectIdOrSlug)}`,
339
+ );
340
+
341
+ // Parse Markdown to HTML if body exists
342
+ let descriptionHtml: string | undefined;
343
+ if (data.body) {
344
+ try {
345
+ descriptionHtml = marked.parse(data.body) as string;
346
+ } catch (e) {
347
+ console.warn('[modrinth] Failed to parse markdown:', e);
348
+ descriptionHtml = data.body; // Fallback to raw text
349
+ }
350
+ }
351
+
352
+ return {
353
+ provider: 'modrinth',
354
+ projectId: data.id,
355
+ slug: data.slug,
356
+ name: data.title,
357
+ summary: data.description,
358
+ description: descriptionHtml || data.body,
359
+ iconUrl: data.icon_url,
360
+ downloads: data.downloads,
361
+ categories: data.categories,
362
+ authors: data.author ? [data.author] : undefined,
363
+ websiteUrl: data.thread_id
364
+ ? `https://modrinth.com/project/${data.slug}`
365
+ : undefined,
366
+ };
367
+ }
368
+
369
+ /**
370
+ * Get MarketplaceItem by project ID (for dependency resolution)
371
+ */
372
+ export async function modrinthGetItemById(
373
+ projectId: string,
374
+ projectType: ProjectType,
375
+ ): Promise<MarketplaceItem | null> {
376
+ try {
377
+ const details = await modrinthGetProjectDetails(projectId);
378
+ return {
379
+ provider: 'modrinth',
380
+ projectType,
381
+ projectId: details.projectId,
382
+ slug: details.slug,
383
+ name: details.name,
384
+ summary: details.summary,
385
+ iconUrl: details.iconUrl,
386
+ downloads: details.downloads,
387
+ };
388
+ } catch (e) {
389
+ console.warn(`[modrinth] Failed to get project ${projectId}:`, e);
390
+ return null;
391
+ }
392
+ }
393
+
394
+ export const modrinthModMarketplaceProvider: ModMarketplaceProvider = {
395
+ id: 'modrinth',
396
+ label: 'Modrinth',
397
+ order: 10,
398
+ search: modrinthSearch,
399
+ install: modrinthInstallToManifestEntry,
400
+ getProjectDetails: modrinthGetProjectDetails,
401
+ getInstallVersions: modrinthGetInstallVersions,
402
+ };
@@ -0,0 +1,77 @@
1
+ import type { ModsProviderLoaderIds } from '../../minecraft-loader/base-loader';
2
+ import { loaderRegistry } from '../../minecraft-loader/loader-registry';
3
+
4
+ type ModsProviderLoaderIdsByProvider = Readonly<
5
+ Partial<Record<string, string | readonly string[]>>
6
+ >;
7
+
8
+ function normalizeToArray(value: string | readonly string[]): string[] {
9
+ if (typeof value === 'string') {
10
+ const trimmed = value.trim();
11
+ return trimmed ? [trimmed] : [];
12
+ }
13
+ return value.map((s) => s.trim()).filter(Boolean);
14
+ }
15
+
16
+ function resolveFromMapping(
17
+ mapping: ModsProviderLoaderIds,
18
+ providerId: string,
19
+ fallbackLoaderId: string,
20
+ ): string[] {
21
+ if (typeof mapping === 'string') {
22
+ return normalizeToArray(mapping);
23
+ }
24
+ if (Array.isArray(mapping)) {
25
+ return normalizeToArray(mapping);
26
+ }
27
+ const byProvider = mapping as ModsProviderLoaderIdsByProvider;
28
+ const forProvider = byProvider[providerId];
29
+ if (forProvider !== undefined) {
30
+ return normalizeToArray(forProvider);
31
+ }
32
+ return [fallbackLoaderId];
33
+ }
34
+
35
+ /**
36
+ * Id загрузчика для фильтрации в конкретном маркетплейсе модов.
37
+ * Берёт `modsProviderLoaderIds` с зарегистрированного лоадера или fallback на `loader.id`.
38
+ */
39
+ export function resolveModsProviderLoaderIds(
40
+ loaderId: string | undefined,
41
+ providerId: string,
42
+ ): string[] {
43
+ if (!loaderId || loaderId === 'vanilla') {
44
+ return [];
45
+ }
46
+
47
+ const loader = loaderRegistry.get(loaderId);
48
+ if (!loader) {
49
+ return [loaderId];
50
+ }
51
+
52
+ const mapping = loader.modsProviderLoaderIds;
53
+ if (!mapping) {
54
+ return [loader.id];
55
+ }
56
+
57
+ return resolveFromMapping(mapping, providerId, loader.id);
58
+ }
59
+
60
+ export function getMarketplaceLoaderIds(
61
+ ctx: { loader?: string; marketplaceLoaderIds?: string[] },
62
+ providerId: string,
63
+ ): string[] {
64
+ if (ctx.marketplaceLoaderIds?.length) {
65
+ return ctx.marketplaceLoaderIds;
66
+ }
67
+ return resolveModsProviderLoaderIds(ctx.loader, providerId);
68
+ }
69
+
70
+ /** Первый id для CurseForge (API принимает один modLoaderType). */
71
+ export function getCurseForgeMarketplaceLoaderId(
72
+ ctx: { loader?: string; marketplaceLoaderIds?: string[] },
73
+ providerId: string = 'curseforge',
74
+ ): string | undefined {
75
+ const ids = getMarketplaceLoaderIds(ctx, providerId);
76
+ return ids[0];
77
+ }
@@ -0,0 +1,76 @@
1
+ export const MARKETPLACE_SEARCH_PAGE_SIZE = 20;
2
+
3
+ export type ModsProviderId = 'modrinth' | 'curseforge' | 'optifine';
4
+
5
+ export type ProjectType = 'mod' | 'resourcepack' | 'shaderpack';
6
+
7
+ export type LoaderId = 'vanilla' | 'fabric' | 'quilt' | 'forge' | 'neoforge' | string;
8
+
9
+ export type MarketplaceItem = {
10
+ provider: ModsProviderId;
11
+ projectType: ProjectType;
12
+ /**
13
+ * Provider-specific project id (Modrinth project_id, CurseForge modId)
14
+ */
15
+ projectId: string;
16
+ /**
17
+ * Human-friendly slug (if provider has it)
18
+ */
19
+ slug: string;
20
+ name: string;
21
+ summary?: string;
22
+ iconUrl?: string;
23
+ downloads?: number;
24
+ };
25
+
26
+ export type MarketplaceSearchContext = {
27
+ projectType: ProjectType;
28
+ query: string;
29
+ minecraftVersion?: string;
30
+ /** Id лоадера в реестре сборки */
31
+ loader?: LoaderId;
32
+ /** Id для фильтрации в конкретном провайдере (из `modsProviderLoaderIds`) */
33
+ marketplaceLoaderIds?: string[];
34
+ /** 0-based страница; Modrinth offset = page * PAGE_SIZE, CurseForge index = page * PAGE_SIZE */
35
+ page?: number;
36
+ };
37
+
38
+ export type MarketplaceSearchResult = {
39
+ items: MarketplaceItem[];
40
+ hasMore: boolean;
41
+ };
42
+
43
+ export type InstallContext = {
44
+ projectType: ProjectType;
45
+ minecraftVersion: string;
46
+ /** Id лоадера в реестре сборки */
47
+ loader: LoaderId;
48
+ /** Id для фильтрации в конкретном провайдере (из `modsProviderLoaderIds`) */
49
+ marketplaceLoaderIds?: string[];
50
+ };
51
+
52
+ export type ProjectDetails = {
53
+ provider: ModsProviderId;
54
+ projectId: string;
55
+ slug: string;
56
+ name: string;
57
+ summary?: string;
58
+ description?: string;
59
+ iconUrl?: string;
60
+ downloads?: number;
61
+ categories?: string[];
62
+ authors?: string[];
63
+ websiteUrl?: string;
64
+ sourceUrl?: string;
65
+ issuesUrl?: string;
66
+ wikiUrl?: string;
67
+ supportUrl?: string;
68
+ };
69
+
70
+ export type MarketplaceInstallVersion = {
71
+ id: string;
72
+ label: string;
73
+ publishedAt?: string;
74
+ recommended?: boolean;
75
+ };
76
+