@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,140 @@
1
+ import type { EntityUser } from '../types/entities';
2
+ import { safeRequest } from '../utils/safeRequest';
3
+ import { graphqlRequest } from './graphql';
4
+
5
+ /** Алиас для совместимости с кодом, который ожидал экспорт типа `Friend`. */
6
+ export type Friend = EntityUser;
7
+
8
+ /**
9
+ * Получает список друзей текущего пользователя
10
+ */
11
+ export const getFriends = () =>
12
+ safeRequest(async (): Promise<EntityUser[]> => {
13
+ const query = `
14
+ query GetFriends {
15
+ authenticatedItem {
16
+ ... on User {
17
+ friends {
18
+ id
19
+ username
20
+ email
21
+ avatar
22
+ status
23
+ statusDetail
24
+ lastSeenAt
25
+ }
26
+ }
27
+ }
28
+ }
29
+ `;
30
+
31
+ const result = await graphqlRequest<{
32
+ authenticatedItem: { friends: EntityUser[] } | null;
33
+ }>(query);
34
+
35
+ return result.authenticatedItem?.friends ?? [];
36
+ });
37
+
38
+ /**
39
+ * Удаляет друга (временно с двух сторон на фронте)
40
+ */
41
+ export const removeFriend = (friendId: string) =>
42
+ safeRequest(async (): Promise<boolean> => {
43
+ const currentUserQuery = `
44
+ query GetCurrentUser {
45
+ authenticatedItem {
46
+ ... on User {
47
+ id
48
+ }
49
+ }
50
+ }
51
+ `;
52
+
53
+ const currentUserResult = await graphqlRequest<{
54
+ authenticatedItem: { id: string } | null;
55
+ }>(currentUserQuery);
56
+
57
+ const currentUserId = currentUserResult.authenticatedItem?.id;
58
+
59
+ if (!currentUserId) {
60
+ throw new Error('User not authenticated');
61
+ }
62
+
63
+ const mutation = `
64
+ mutation RemoveFriend($where: UserWhereUniqueInput!, $data: UserUpdateInput!) {
65
+ updateUser(where: $where, data: $data) {
66
+ id
67
+ }
68
+ }
69
+ `;
70
+
71
+ await graphqlRequest(mutation, {
72
+ where: { id: currentUserId },
73
+ data: {
74
+ friends: {
75
+ disconnect: [{ id: friendId }],
76
+ },
77
+ },
78
+ });
79
+
80
+ // TODO: перенести на backend
81
+ await graphqlRequest(mutation, {
82
+ where: { id: friendId },
83
+ data: {
84
+ friends: {
85
+ disconnect: [{ id: currentUserId }],
86
+ },
87
+ },
88
+ });
89
+
90
+ return true;
91
+ });
92
+
93
+ /**
94
+ * Ищет пользователей по имени или email
95
+ */
96
+ export const searchUsers = (
97
+ query: string,
98
+ options?: {
99
+ excludeFriendIds?: string[];
100
+ currentUserId?: string;
101
+ },
102
+ ) =>
103
+ safeRequest(async (): Promise<EntityUser[]> => {
104
+ const searchQuery = `
105
+ query SearchUsers($where: UserWhereInput!) {
106
+ users(where: $where, take: 20) {
107
+ id
108
+ username
109
+ email
110
+ avatar
111
+ status
112
+ statusDetail
113
+ lastSeenAt
114
+ }
115
+ }
116
+ `;
117
+
118
+ const excludeIds = [
119
+ ...(options?.excludeFriendIds ?? []),
120
+ ...(options?.currentUserId ? [options.currentUserId] : []),
121
+ ];
122
+
123
+ const where: Record<string, unknown> = {
124
+ OR: [
125
+ { username: { contains: query, mode: 'insensitive' } },
126
+ { email: { contains: query, mode: 'insensitive' } },
127
+ ],
128
+ ...(excludeIds.length && {
129
+ id: {
130
+ not: { in: excludeIds },
131
+ },
132
+ }),
133
+ };
134
+
135
+ const result = await graphqlRequest<{ users: EntityUser[] }>(searchQuery, {
136
+ where,
137
+ });
138
+
139
+ return result.users;
140
+ });
@@ -0,0 +1,87 @@
1
+ /**
2
+ * GraphQL клиент для работы с Keystone API
3
+ */
4
+
5
+ import { getGraphQLUrl as getGraphQLUrlFromConfig } from './config';
6
+
7
+ export interface GraphQLResponse<T = any> {
8
+ data?: T;
9
+ errors?: Array<{
10
+ message: string;
11
+ locations?: Array<{ line: number; column: number }>;
12
+ path?: Array<string | number>;
13
+ }>;
14
+ }
15
+
16
+ export interface GraphQLRequestOptions {
17
+ headers?: Record<string, string>;
18
+ }
19
+
20
+ /**
21
+ * Выполняет GraphQL запрос
22
+ */
23
+ export async function graphqlRequest<T = any>(
24
+ query: string,
25
+ variables?: Record<string, any>,
26
+ options?: GraphQLRequestOptions
27
+ ): Promise<T> {
28
+ const token = getSessionToken();
29
+
30
+ const response = await fetch(getGraphQLUrlFromConfig(), {
31
+ method: 'POST',
32
+ headers: {
33
+ 'Content-Type': 'application/json',
34
+ ...(token && { Authorization: `Bearer ${token}` }),
35
+ ...options?.headers,
36
+ },
37
+ credentials: 'include', // Важно для работы с cookies (если Keystone использует cookie-based auth)
38
+ body: JSON.stringify({
39
+ query,
40
+ variables,
41
+ }),
42
+ });
43
+
44
+ if (!response.ok) {
45
+ const errorText = await response.text().catch(() => 'Unknown error');
46
+ throw new Error(`HTTP ${response.status}: ${errorText}`);
47
+ }
48
+
49
+ const result: GraphQLResponse<T> = await response.json();
50
+
51
+ if (result.errors && result.errors.length > 0) {
52
+ // Берем первое сообщение об ошибке (обычно это основная ошибка)
53
+ const errorMessage = result.errors[0].message;
54
+ throw new Error(errorMessage);
55
+ }
56
+
57
+ if (!result.data) {
58
+ throw new Error('No data returned from GraphQL query');
59
+ }
60
+
61
+ return result.data;
62
+ }
63
+
64
+ /**
65
+ * Получает токен сессии из localStorage
66
+ */
67
+ export function getSessionToken(): string | null {
68
+ if (typeof window === 'undefined') return null;
69
+ return localStorage.getItem('session_token');
70
+ }
71
+
72
+ /**
73
+ * Сохраняет токен сессии в localStorage
74
+ */
75
+ export function setSessionToken(token: string): void {
76
+ if (typeof window === 'undefined') return;
77
+ localStorage.setItem('session_token', token);
78
+ }
79
+
80
+ /**
81
+ * Удаляет токен сессии из localStorage
82
+ */
83
+ export function removeSessionToken(): void {
84
+ if (typeof window === 'undefined') return;
85
+ localStorage.removeItem('session_token');
86
+ }
87
+
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Экспорт всех API модулей
3
+ */
4
+
5
+ export * from './config';
6
+ export * from './graphql';
7
+ export * from './auth';
8
+ export * from './users';
9
+ export * from './assets';
10
+ export * from './maps';
11
+ export * from './builds';
12
+ export * from './projectServers';
13
+ export * from './posts';
14
+ export * from './events';
15
+ export * from './serverMembers';
16
+ export * from './invites';
17
+ export * from './friends';
18
+ export * from './library';
19
+ export * from './downloads';
20
+ export * from './download-stats';
21
+ export * from './entity-authorship';
22
+ export * from './notify-websocket';
23
+
@@ -0,0 +1,262 @@
1
+ /**
2
+ * API для работы с инвайтами
3
+ */
4
+
5
+ import type { EntityInvite } from '../types/entities';
6
+ import { safeRequest } from '../utils/safeRequest';
7
+ import { graphqlRequest } from './graphql';
8
+
9
+ export interface CreateInviteInput {
10
+ targetId: string;
11
+ type: EntityInvite['type'];
12
+ config?: Record<string, any>;
13
+ }
14
+
15
+ /**
16
+ * Получает список входящих инвайтов (где текущий пользователь - цель)
17
+ */
18
+ export const getIncomingInvites = (
19
+ currentUserId: string,
20
+ options?: {
21
+ type?: EntityInvite['type'];
22
+ status?: EntityInvite['status'];
23
+ },
24
+ ) =>
25
+ safeRequest(async (): Promise<EntityInvite[]> => {
26
+ const query = `
27
+ query GetIncomingInvites($where: InviteWhereInput!, $orderBy: [InviteOrderByInput!]!) {
28
+ invites(where: $where, orderBy: $orderBy) {
29
+ id
30
+ type
31
+ status
32
+ config
33
+ createdAt
34
+ updatedAt
35
+ author {
36
+ id
37
+ username
38
+ email
39
+ avatar
40
+ }
41
+ target {
42
+ id
43
+ username
44
+ email
45
+ avatar
46
+ }
47
+ }
48
+ }
49
+ `;
50
+
51
+ const where: any = {
52
+ target: { id: { equals: currentUserId } },
53
+ };
54
+
55
+ if (options?.type) {
56
+ where.type = { equals: options.type };
57
+ }
58
+
59
+ if (options?.status) {
60
+ where.status = { equals: options.status };
61
+ }
62
+
63
+ const orderBy = [{ createdAt: 'desc' as const }];
64
+
65
+ const result = await graphqlRequest<{ invites: EntityInvite[] }>(query, {
66
+ where,
67
+ orderBy,
68
+ });
69
+
70
+ return result.invites;
71
+ });
72
+
73
+ /**
74
+ * Получает список исходящих инвайтов (где текущий пользователь - автор)
75
+ */
76
+ export const getOutgoingInvites = (
77
+ currentUserId: string,
78
+ options?: {
79
+ type?: EntityInvite['type'];
80
+ status?: EntityInvite['status'];
81
+ },
82
+ ) =>
83
+ safeRequest(async (): Promise<EntityInvite[]> => {
84
+ const query = `
85
+ query GetOutgoingInvites($where: InviteWhereInput!, $orderBy: [InviteOrderByInput!]!) {
86
+ invites(where: $where, orderBy: $orderBy) {
87
+ id
88
+ type
89
+ status
90
+ config
91
+ createdAt
92
+ updatedAt
93
+ author {
94
+ id
95
+ username
96
+ email
97
+ avatar
98
+ }
99
+ target {
100
+ id
101
+ username
102
+ email
103
+ avatar
104
+ }
105
+ }
106
+ }
107
+ `;
108
+
109
+ const where: any = {
110
+ author: { id: { equals: currentUserId } },
111
+ };
112
+
113
+ if (options?.type) {
114
+ where.type = { equals: options.type };
115
+ }
116
+
117
+ if (options?.status) {
118
+ where.status = { equals: options.status };
119
+ }
120
+
121
+ const orderBy = [{ createdAt: 'desc' as const }];
122
+
123
+ const result = await graphqlRequest<{ invites: EntityInvite[] }>(query, {
124
+ where,
125
+ orderBy,
126
+ });
127
+
128
+ return result.invites;
129
+ });
130
+
131
+ /**
132
+ * Создает новый инвайт
133
+ */
134
+ export const createInvite = (input: CreateInviteInput) =>
135
+ safeRequest(async (): Promise<EntityInvite> => {
136
+ const mutation = `
137
+ mutation CreateInvite($data: InviteCreateInput!) {
138
+ createInvite(data: $data) {
139
+ id
140
+ type
141
+ status
142
+ config
143
+ createdAt
144
+ updatedAt
145
+ author {
146
+ id
147
+ username
148
+ email
149
+ avatar
150
+ }
151
+ target {
152
+ id
153
+ username
154
+ email
155
+ avatar
156
+ }
157
+ }
158
+ }
159
+ `;
160
+
161
+ const result = await graphqlRequest<{ createInvite: EntityInvite }>(
162
+ mutation,
163
+ {
164
+ data: {
165
+ target: { connect: { id: input.targetId } },
166
+ type: input.type,
167
+ config: input.config || {},
168
+ },
169
+ },
170
+ );
171
+
172
+ return result.createInvite;
173
+ });
174
+ /**
175
+ * Принимает инвайт (обновляет статус на accepted)
176
+ */
177
+ export const acceptInvite = (inviteId: string) =>
178
+ safeRequest(async (): Promise<EntityInvite> => {
179
+ const mutation = `
180
+ mutation AcceptInvite($where: InviteWhereUniqueInput!, $data: InviteUpdateInput!) {
181
+ updateInvite(where: $where, data: $data) {
182
+ id
183
+ type
184
+ status
185
+ config
186
+ createdAt
187
+ updatedAt
188
+ author {
189
+ id
190
+ username
191
+ email
192
+ avatar
193
+ }
194
+ target {
195
+ id
196
+ username
197
+ email
198
+ avatar
199
+ }
200
+ }
201
+ }
202
+ `;
203
+
204
+ const result = await graphqlRequest<{ updateInvite: EntityInvite }>(
205
+ mutation,
206
+ {
207
+ where: { id: inviteId },
208
+ data: {
209
+ status: 'accepted',
210
+ },
211
+ },
212
+ );
213
+
214
+ return result.updateInvite;
215
+ });
216
+
217
+ /**
218
+ * Отклоняет инвайт (удаляет его)
219
+ */
220
+ export const rejectInvite = (inviteId: string) =>
221
+ safeRequest(async (): Promise<boolean> => {
222
+ const mutation = `
223
+ mutation RejectInvite($where: InviteWhereUniqueInput!) {
224
+ deleteInvite(where: $where) {
225
+ id
226
+ }
227
+ }
228
+ `;
229
+
230
+ await graphqlRequest<{ deleteInvite: { id: string } }>(mutation, {
231
+ where: { id: inviteId },
232
+ });
233
+
234
+ return true;
235
+ });
236
+
237
+ /**
238
+ * Проверяет, отправлен ли уже инвайт в друзья указанному пользователю
239
+ */
240
+ export const checkFriendInviteExists = (targetId: string) =>
241
+ safeRequest(async (): Promise<boolean> => {
242
+ const query = `
243
+ query CheckFriendInviteExists($where: InviteWhereInput!) {
244
+ invites(where: $where, take: 1) {
245
+ id
246
+ }
247
+ }
248
+ `;
249
+
250
+ const result = await graphqlRequest<{ invites: Array<{ id: string }> }>(
251
+ query,
252
+ {
253
+ where: {
254
+ type: { equals: 'friend' },
255
+ target: { id: { equals: targetId } },
256
+ status: { equals: 'pending' },
257
+ },
258
+ },
259
+ );
260
+
261
+ return result.invites.length > 0;
262
+ });
@@ -0,0 +1,44 @@
1
+ /**
2
+ * API для страницы библиотеки (статистика через стандартные count-запросы)
3
+ */
4
+
5
+ import { graphqlRequest } from './graphql';
6
+
7
+ export interface LibraryStats {
8
+ usersOnline: number;
9
+ usersTotal: number;
10
+ serversCount: number;
11
+ buildsCount: number;
12
+ mapsCount: number;
13
+ }
14
+
15
+ /**
16
+ * Получает сводную статистику для страницы библиотеки —
17
+ * один запрос с фильтрацией по каждой сущности (usersCount, buildsCount, projectServersCount).
18
+ */
19
+ export async function getLibraryStats(): Promise<LibraryStats> {
20
+ const query = `
21
+ query LibraryStatsCounts {
22
+ usersOnline: usersCount(where: { status: { equals: "online" } })
23
+ usersTotal: usersCount(where: {})
24
+ serversCount: projectServersCount(where: {})
25
+ buildsCount: buildsCount(where: { isPublic: { equals: true } })
26
+ }
27
+ `;
28
+
29
+ const result = await graphqlRequest<{
30
+ usersOnline: number;
31
+ usersTotal: number;
32
+ serversCount: number;
33
+ buildsCount: number;
34
+ mapsCount: number;
35
+ }>(query);
36
+
37
+ return {
38
+ usersOnline: result.usersOnline,
39
+ usersTotal: result.usersTotal,
40
+ serversCount: result.serversCount,
41
+ buildsCount: result.buildsCount,
42
+ mapsCount: result.mapsCount,
43
+ };
44
+ }