@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,103 @@
1
+ /**
2
+ * Дневная статистика скачиваний (стандартный GraphQL Keystone)
3
+ */
4
+
5
+ import { safeRequest } from '../utils/safeRequest';
6
+ import { graphqlRequest } from './graphql';
7
+
8
+ export type DownloadDailyStatPoint = {
9
+ date: string;
10
+ count: number;
11
+ };
12
+
13
+ function formatDateKey(iso: string): string {
14
+ return iso.slice(0, 10);
15
+ }
16
+
17
+ const downloadDailyStatsQuery = `
18
+ query DownloadDailyStats(
19
+ $where: DownloadDailyStatWhereInput!
20
+ $orderBy: [DownloadDailyStatOrderByInput!]!
21
+ ) {
22
+ downloadDailyStats(where: $where, orderBy: $orderBy) {
23
+ date
24
+ count
25
+ }
26
+ }
27
+ `;
28
+
29
+ export const getBuildDownloadDailyStats = (
30
+ buildId: string,
31
+ options?: { from?: string; to?: string },
32
+ ) =>
33
+ safeRequest(async (): Promise<DownloadDailyStatPoint[]> => {
34
+ const to = options?.to ?? formatDateKey(new Date().toISOString());
35
+ const from =
36
+ options?.from ??
37
+ formatDateKey(
38
+ new Date(
39
+ Date.UTC(
40
+ new Date().getUTCFullYear(),
41
+ new Date().getUTCMonth(),
42
+ new Date().getUTCDate() - 30,
43
+ ),
44
+ ).toISOString(),
45
+ );
46
+
47
+ const result = await graphqlRequest<{
48
+ downloadDailyStats: Array<{ date: string; count: number }>;
49
+ }>(downloadDailyStatsQuery, {
50
+ where: {
51
+ AND: [
52
+ { targetType: { equals: 'build' } },
53
+ { targetId: { equals: buildId } },
54
+ { date: { gte: `${from}T00:00:00.000Z` } },
55
+ { date: { lte: `${to}T23:59:59.999Z` } },
56
+ ],
57
+ },
58
+ orderBy: [{ date: 'asc' }],
59
+ });
60
+
61
+ return result.downloadDailyStats.map((row) => ({
62
+ date: formatDateKey(row.date),
63
+ count: Number(row.count) || 0,
64
+ }));
65
+ });
66
+
67
+ export const getMapDownloadDailyStats = (
68
+ mapId: string,
69
+ options?: { from?: string; to?: string },
70
+ ) =>
71
+ safeRequest(async (): Promise<DownloadDailyStatPoint[]> => {
72
+ const to = options?.to ?? formatDateKey(new Date().toISOString());
73
+ const from =
74
+ options?.from ??
75
+ formatDateKey(
76
+ new Date(
77
+ Date.UTC(
78
+ new Date().getUTCFullYear(),
79
+ new Date().getUTCMonth(),
80
+ new Date().getUTCDate() - 30,
81
+ ),
82
+ ).toISOString(),
83
+ );
84
+
85
+ const result = await graphqlRequest<{
86
+ downloadDailyStats: Array<{ date: string; count: number }>;
87
+ }>(downloadDailyStatsQuery, {
88
+ where: {
89
+ AND: [
90
+ { targetType: { equals: 'map' } },
91
+ { targetId: { equals: mapId } },
92
+ { date: { gte: `${from}T00:00:00.000Z` } },
93
+ { date: { lte: `${to}T23:59:59.999Z` } },
94
+ ],
95
+ },
96
+ orderBy: [{ date: 'asc' }],
97
+ });
98
+
99
+ return result.downloadDailyStats.map((row) => ({
100
+ date: formatDateKey(row.date),
101
+ count: Number(row.count) || 0,
102
+ }));
103
+ });
@@ -0,0 +1,36 @@
1
+ /**
2
+ * API учёта скачиваний сборок и карт
3
+ */
4
+
5
+ import { safeRequest } from '../utils/safeRequest';
6
+ import { graphqlRequest } from './graphql';
7
+
8
+ export const incrementBuildDownloads = (buildId: string) =>
9
+ safeRequest(async (): Promise<number> => {
10
+ const mutation = `
11
+ mutation IncrementBuildDownloads($buildId: ID!) {
12
+ incrementBuildDownloads(buildId: $buildId)
13
+ }
14
+ `;
15
+
16
+ const result = await graphqlRequest<{
17
+ incrementBuildDownloads: number;
18
+ }>(mutation, { buildId });
19
+
20
+ return result.incrementBuildDownloads;
21
+ });
22
+
23
+ export const incrementMapDownloads = (mapId: string) =>
24
+ safeRequest(async (): Promise<number> => {
25
+ const mutation = `
26
+ mutation IncrementMapDownloads($mapId: ID!) {
27
+ incrementMapDownloads(mapId: $mapId)
28
+ }
29
+ `;
30
+
31
+ const result = await graphqlRequest<{
32
+ incrementMapDownloads: number;
33
+ }>(mutation, { mapId });
34
+
35
+ return result.incrementMapDownloads;
36
+ });
@@ -0,0 +1,60 @@
1
+ import { safeRequest } from '../utils/safeRequest';
2
+ import { graphqlRequest } from './graphql';
3
+
4
+ export type PublishedEntityAuthor = {
5
+ id: string;
6
+ username: string;
7
+ };
8
+
9
+ /**
10
+ * Автор опубликованной сборки с бэкенда (не из локального манифеста).
11
+ */
12
+ export const getBuildAuthor = (buildId: string) =>
13
+ safeRequest(async (): Promise<PublishedEntityAuthor | null> => {
14
+ const query = `
15
+ query GetBuildAuthor($id: ID!) {
16
+ build(where: { id: $id }) {
17
+ author {
18
+ id
19
+ username
20
+ }
21
+ }
22
+ }
23
+ `;
24
+
25
+ const result = await graphqlRequest<{
26
+ build: { author: PublishedEntityAuthor } | null;
27
+ }>(query, { id: buildId });
28
+
29
+ return result.build?.author ?? null;
30
+ });
31
+
32
+ /**
33
+ * Автор опубликованной карты с бэкенда.
34
+ */
35
+ export const getMapAuthor = (mapId: string) =>
36
+ safeRequest(async (): Promise<PublishedEntityAuthor | null> => {
37
+ const query = `
38
+ query GetMapAuthor($id: ID!) {
39
+ map(where: { id: $id }) {
40
+ author {
41
+ id
42
+ username
43
+ }
44
+ }
45
+ }
46
+ `;
47
+
48
+ const result = await graphqlRequest<{
49
+ map: { author: PublishedEntityAuthor } | null;
50
+ }>(query, { id: mapId });
51
+
52
+ return result.map?.author ?? null;
53
+ });
54
+
55
+ export function isUserEntityAuthor(
56
+ author: PublishedEntityAuthor | null | undefined,
57
+ userId: string | null | undefined,
58
+ ): boolean {
59
+ return !!(author?.id && userId && author.id === userId);
60
+ }
@@ -0,0 +1,393 @@
1
+ /**
2
+ * API для работы с мероприятиями проектов
3
+ */
4
+
5
+ import type { EntityEvent } from '../types/entities';
6
+ import { safeRequest } from '../utils/safeRequest';
7
+ import { graphqlRequest } from './graphql';
8
+
9
+ export type Event = EntityEvent;
10
+
11
+ export interface EventInput {
12
+ projectId?: string; // Опционально - событие может быть без проекта
13
+ serverId?: string; // Опционально - событие может быть привязано к серверу
14
+ title: string;
15
+ description: string;
16
+ startDateTime: string; // Дата и время начала (объединены)
17
+ endTime?: string; // Время окончания (опционально)
18
+ image?: string;
19
+ attachments?: string[];
20
+ }
21
+
22
+ /**
23
+ * Получает все мероприятия (для главной страницы)
24
+ */
25
+ export const getAllEvents = (options?: {
26
+ take?: number;
27
+ skip?: number;
28
+ orderBy?: Array<{ startDateTime?: 'asc' | 'desc' }>;
29
+ }) =>
30
+ safeRequest(async (): Promise<EntityEvent[]> => {
31
+ const query = `
32
+ query GetAllEvents($orderBy: [EventOrderByInput!]!, $take: Int, $skip: Int!) {
33
+ events(orderBy: $orderBy, take: $take, skip: $skip) {
34
+ id
35
+ title
36
+ description
37
+ startDateTime
38
+ endTime
39
+ participants
40
+ image
41
+ attachments
42
+ isActive
43
+ project {
44
+ id
45
+ name
46
+ }
47
+ server {
48
+ id
49
+ name
50
+ }
51
+ }
52
+ }
53
+ `;
54
+
55
+ const orderBy = options?.orderBy || [{ startDateTime: 'asc' }];
56
+
57
+ const result = await graphqlRequest<{ events: EntityEvent[] }>(query, {
58
+ orderBy,
59
+ take: options?.take || 20,
60
+ skip: options?.skip || 0,
61
+ });
62
+
63
+ return result.events;
64
+ });
65
+
66
+ /**
67
+ * Получает мероприятие по ID
68
+ */
69
+ export const getEvent = (eventId: string) =>
70
+ safeRequest(async (): Promise<EntityEvent> => {
71
+ const query = `
72
+ query GetEvent($where: EventWhereUniqueInput!) {
73
+ event(where: $where) {
74
+ id
75
+ title
76
+ description
77
+ startDateTime
78
+ endTime
79
+ participants
80
+ image
81
+ attachments
82
+ isActive
83
+ project {
84
+ id
85
+ name
86
+ }
87
+ server {
88
+ id
89
+ name
90
+ }
91
+ }
92
+ }
93
+ `;
94
+
95
+ const result = await graphqlRequest<{ event: EntityEvent }>(query, {
96
+ where: { id: eventId },
97
+ });
98
+
99
+ return result.event;
100
+ });
101
+
102
+ /**
103
+ * Получает список мероприятий проекта
104
+ */
105
+ export const getProjectEvents = (
106
+ projectId: string,
107
+ options?: {
108
+ take?: number;
109
+ skip?: number;
110
+ orderBy?: Array<{ startDateTime?: 'asc' | 'desc' }>;
111
+ filter?: 'all' | 'active' | 'upcoming' | 'past';
112
+ },
113
+ ) =>
114
+ safeRequest(async (): Promise<EntityEvent[]> => {
115
+ const query = `
116
+ query GetProjectEvents($where: EventWhereInput!, $orderBy: [EventOrderByInput!]!, $take: Int, $skip: Int!) {
117
+ events(where: $where, orderBy: $orderBy, take: $take, skip: $skip) {
118
+ id
119
+ title
120
+ description
121
+ startDateTime
122
+ endTime
123
+ participants
124
+ image
125
+ attachments
126
+ isActive
127
+ project {
128
+ id
129
+ name
130
+ }
131
+ server {
132
+ id
133
+ name
134
+ }
135
+ }
136
+ }
137
+ `;
138
+
139
+ const where: any = {
140
+ project: { id: { equals: projectId } },
141
+ };
142
+
143
+ const now = new Date().toISOString();
144
+
145
+ if (options?.filter === 'active') {
146
+ // Активные мероприятия: текущая дата между началом и концом
147
+ // startDateTime <= now AND (endTime >= now OR endTime IS NULL)
148
+ where.AND = [
149
+ { startDateTime: { lte: now } },
150
+ {
151
+ OR: [{ endTime: { gte: now } }, { endTime: null }],
152
+ },
153
+ ];
154
+ } else if (options?.filter === 'upcoming') {
155
+ // Предстоящие мероприятия: начало в будущем
156
+ where.startDateTime = { gte: now };
157
+ } else if (options?.filter === 'past') {
158
+ // Прошедшие мероприятия: дата окончания была раньше текущего времени
159
+ // (endTime < now) OR (endTime IS NULL AND startDateTime < now)
160
+ where.OR = [
161
+ { endTime: { lt: now } },
162
+ {
163
+ AND: [{ endTime: null }, { startDateTime: { lt: now } }],
164
+ },
165
+ ];
166
+ }
167
+
168
+ const orderBy = options?.orderBy || [{ startDateTime: 'asc' }];
169
+
170
+ const result = await graphqlRequest<{ events: EntityEvent[] }>(query, {
171
+ where,
172
+ orderBy,
173
+ take: options?.take || 20,
174
+ skip: options?.skip || 0,
175
+ });
176
+
177
+ return result.events;
178
+ });
179
+
180
+ /**
181
+ * Получает список мероприятий сервера
182
+ */
183
+ export const getServerEvents = (
184
+ serverId: string,
185
+ options?: {
186
+ take?: number;
187
+ skip?: number;
188
+ orderBy?: Array<{ startDateTime?: 'asc' | 'desc' }>;
189
+ filter?: 'all' | 'active' | 'upcoming' | 'past';
190
+ },
191
+ ) =>
192
+ safeRequest(async (): Promise<EntityEvent[]> => {
193
+ const query = `
194
+ query GetServerEvents($where: EventWhereInput!, $orderBy: [EventOrderByInput!]!, $take: Int, $skip: Int!) {
195
+ events(where: $where, orderBy: $orderBy, take: $take, skip: $skip) {
196
+ id
197
+ title
198
+ description
199
+ startDateTime
200
+ endTime
201
+ participants
202
+ image
203
+ attachments
204
+ isActive
205
+ project {
206
+ id
207
+ name
208
+ }
209
+ server {
210
+ id
211
+ name
212
+ }
213
+ }
214
+ }
215
+ `;
216
+
217
+ const where: any = {
218
+ server: { id: { equals: serverId } },
219
+ };
220
+
221
+ const now = new Date().toISOString();
222
+
223
+ if (options?.filter === 'active') {
224
+ // Активные мероприятия: текущая дата между началом и концом
225
+ // startDateTime <= now AND (endTime >= now OR endTime IS NULL)
226
+ where.AND = [
227
+ { startDateTime: { lte: now } },
228
+ {
229
+ OR: [{ endTime: { gte: now } }, { endTime: null }],
230
+ },
231
+ ];
232
+ } else if (options?.filter === 'upcoming') {
233
+ // Предстоящие мероприятия: начало в будущем
234
+ where.startDateTime = { gte: now };
235
+ } else if (options?.filter === 'past') {
236
+ // Прошедшие мероприятия: дата окончания была раньше текущего времени
237
+ // (endTime < now) OR (endTime IS NULL AND startDateTime < now)
238
+ where.OR = [
239
+ { endTime: { lt: now } },
240
+ {
241
+ AND: [{ endTime: null }, { startDateTime: { lt: now } }],
242
+ },
243
+ ];
244
+ }
245
+
246
+ const orderBy = options?.orderBy || [{ startDateTime: 'asc' }];
247
+
248
+ const result = await graphqlRequest<{ events: EntityEvent[] }>(query, {
249
+ where,
250
+ orderBy,
251
+ take: options?.take || 20,
252
+ skip: options?.skip || 0,
253
+ });
254
+
255
+ return result.events;
256
+ });
257
+
258
+ /**
259
+ * Создает новое мероприятие
260
+ */
261
+ export const createEvent = (data: EventInput) =>
262
+ safeRequest(async (): Promise<EntityEvent> => {
263
+ const mutation = `
264
+ mutation CreateEvent($data: EventCreateInput!) {
265
+ createEvent(data: $data) {
266
+ id
267
+ title
268
+ description
269
+ startDateTime
270
+ endTime
271
+ participants
272
+ image
273
+ attachments
274
+ isActive
275
+ project {
276
+ id
277
+ name
278
+ }
279
+ server {
280
+ id
281
+ name
282
+ }
283
+ }
284
+ }
285
+ `;
286
+
287
+ const createData: any = {
288
+ title: data.title,
289
+ description: data.description,
290
+ startDateTime: data.startDateTime,
291
+ endTime: data.endTime,
292
+ image: data.image || '',
293
+ attachments: data.attachments ?? [],
294
+ };
295
+
296
+ // Привязываем к проекту или серверу, если указаны
297
+ if (data.projectId) {
298
+ createData.project = { connect: { id: data.projectId } };
299
+ }
300
+ if (data.serverId) {
301
+ createData.server = { connect: { id: data.serverId } };
302
+ }
303
+
304
+ const result = await graphqlRequest<{ createEvent: EntityEvent }>(
305
+ mutation,
306
+ {
307
+ data: createData,
308
+ },
309
+ );
310
+
311
+ return result.createEvent;
312
+ });
313
+
314
+ /**
315
+ * Обновляет мероприятие
316
+ */
317
+ export const updateEvent = (
318
+ eventId: string,
319
+ data: Partial<Omit<EventInput, 'projectId'>>,
320
+ ) =>
321
+ safeRequest(async (): Promise<EntityEvent> => {
322
+ const mutation = `
323
+ mutation UpdateEvent($where: EventWhereUniqueInput!, $data: EventUpdateInput!) {
324
+ updateEvent(where: $where, data: $data) {
325
+ id
326
+ title
327
+ description
328
+ startDateTime
329
+ endTime
330
+ participants
331
+ image
332
+ attachments
333
+ isActive
334
+ project {
335
+ id
336
+ name
337
+ }
338
+ server {
339
+ id
340
+ name
341
+ }
342
+ }
343
+ }
344
+ `;
345
+
346
+ const updateData: any = {};
347
+ if (data.title !== undefined) updateData.title = data.title;
348
+ if (data.description !== undefined)
349
+ updateData.description = data.description;
350
+ if (data.startDateTime !== undefined)
351
+ updateData.startDateTime = data.startDateTime;
352
+ if (data.endTime !== undefined) updateData.endTime = data.endTime;
353
+ if (data.image !== undefined) updateData.image = data.image;
354
+ if (data.attachments !== undefined) updateData.attachments = data.attachments;
355
+ if (data.serverId !== undefined) {
356
+ updateData.server = data.serverId
357
+ ? { connect: { id: data.serverId } }
358
+ : { disconnect: true };
359
+ }
360
+
361
+ const result = await graphqlRequest<{ updateEvent: EntityEvent }>(
362
+ mutation,
363
+ {
364
+ where: { id: eventId },
365
+ data: updateData,
366
+ },
367
+ );
368
+
369
+ return result.updateEvent;
370
+ });
371
+
372
+ /**
373
+ * Удаляет мероприятие
374
+ */
375
+ export const deleteEvent = (eventId: string) =>
376
+ safeRequest(async (): Promise<EntityEvent> => {
377
+ const mutation = `
378
+ mutation DeleteEvent($where: EventWhereUniqueInput!) {
379
+ deleteEvent(where: $where) {
380
+ id
381
+ }
382
+ }
383
+ `;
384
+
385
+ const result = await graphqlRequest<{ deleteEvent: EntityEvent }>(
386
+ mutation,
387
+ {
388
+ where: { id: eventId },
389
+ },
390
+ );
391
+
392
+ return result.deleteEvent;
393
+ });