@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,217 @@
1
+ import type { ThemeVariant } from '../themes';
2
+ import { getAppDataPath } from './app-paths';
3
+
4
+ // Проверка на наличие Node.js окружения (NW.js)
5
+ const isNodeEnv = typeof window !== 'undefined' && (window as any).nw;
6
+
7
+ // Динамическая загрузка Node.js модулей
8
+ let fs: any;
9
+ let path: any;
10
+
11
+ if (isNodeEnv) {
12
+ try {
13
+ const nw = (window as any).nw;
14
+ fs = nw.require('fs');
15
+ path = nw.require('path');
16
+ } catch (error) {
17
+ console.error('Не удалось загрузить Node.js модули:', error);
18
+ }
19
+ }
20
+
21
+ /**
22
+ * Путь к файлу с настройками
23
+ */
24
+ function getSettingsFilePath(): string {
25
+ if (!isNodeEnv || !path) {
26
+ throw new Error('Node.js окружение недоступно');
27
+ }
28
+ const appDataPath = getAppDataPath();
29
+ return path.join(appDataPath, 'settings.json');
30
+ }
31
+
32
+ /**
33
+ * Структура файла настроек
34
+ */
35
+ export interface LocalSettings {
36
+ authorMode: boolean | null;
37
+ notificationMode: 'do_not_disturb' | 'mentions_only' | 'all_messages';
38
+ /** UI theme; default dark for backward compatibility */
39
+ themeVariant?: ThemeVariant;
40
+ /** Theme identifier (base, pink, black, classic, etc.) */
41
+ theme?: string;
42
+ /** UI corner radius scale */
43
+ radiusScale?: 'none' | 'standard' | 'medium';
44
+ defaultMaxRam: number;
45
+ discordRpcEnabled: boolean;
46
+ /** Автообновление расширений с маркетплейса при старте (semver `manifest.version`). */
47
+ extensionsAutoUpdate?: boolean;
48
+ /** Отключить проигрывание звуковых эффектов лаунчера. */
49
+ disableSounds?: boolean;
50
+ /** Отключить автозапуск при старте системы (инверсия UI «Автозапуск»). */
51
+ disableAutostart?: boolean;
52
+ /** Запускать лаунчер свёрнутым в системный трей. */
53
+ startInTray?: boolean;
54
+ version?: number;
55
+ }
56
+
57
+ /**
58
+ * Версия формата хранилища
59
+ */
60
+ const STORAGE_VERSION = 1;
61
+
62
+ /**
63
+ * Значения по умолчанию
64
+ */
65
+ const DEFAULT_SETTINGS: LocalSettings = {
66
+ authorMode: null,
67
+ notificationMode: 'all_messages',
68
+ theme: 'base',
69
+ radiusScale: 'standard',
70
+ defaultMaxRam: 2048,
71
+ discordRpcEnabled: false,
72
+ extensionsAutoUpdate: true,
73
+ disableSounds: false,
74
+ disableAutostart: false,
75
+ startInTray: false,
76
+ version: STORAGE_VERSION,
77
+ };
78
+
79
+ /**
80
+ * Загрузить настройки из файла
81
+ */
82
+ export function loadSettings(): LocalSettings {
83
+ if (!isNodeEnv || !fs || !path) {
84
+ console.warn(
85
+ 'Node.js окружение недоступно, возвращаем настройки по умолчанию',
86
+ );
87
+ return { ...DEFAULT_SETTINGS };
88
+ }
89
+
90
+ try {
91
+ const filePath = getSettingsFilePath();
92
+
93
+ if (!fs.existsSync(filePath)) {
94
+ // Файл не существует, возвращаем настройки по умолчанию
95
+ return { ...DEFAULT_SETTINGS };
96
+ }
97
+
98
+ const content = fs.readFileSync(filePath, 'utf-8');
99
+ const settings: any = JSON.parse(content);
100
+
101
+ // Проверяем версию формата
102
+ if (settings.version !== STORAGE_VERSION) {
103
+ console.warn(
104
+ `Версия формата хранилища (${settings.version}) не совпадает с текущей (${STORAGE_VERSION})`,
105
+ );
106
+ // Можно добавить миграцию здесь
107
+ }
108
+
109
+ // Объединяем с настройками по умолчанию для обратной совместимости
110
+ // Важно: если authorMode явно указан в файле (включая null), используем его
111
+ const merged: LocalSettings = {
112
+ ...DEFAULT_SETTINGS,
113
+ version: STORAGE_VERSION,
114
+ };
115
+
116
+ // Если authorMode присутствует в загруженных настройках (даже если null), используем его
117
+ if (settings.hasOwnProperty('authorMode')) {
118
+ merged.authorMode = settings.authorMode;
119
+ }
120
+ if (settings.hasOwnProperty('notificationMode')) {
121
+ merged.notificationMode = settings.notificationMode;
122
+ }
123
+ if (settings.hasOwnProperty('theme')) {
124
+ merged.theme = settings.theme;
125
+ }
126
+ if (settings.hasOwnProperty('radiusScale')) {
127
+ const r = settings.radiusScale;
128
+ merged.radiusScale =
129
+ r === 'none' || r === 'standard' || r === 'medium'
130
+ ? r
131
+ : DEFAULT_SETTINGS.radiusScale;
132
+ }
133
+ if (settings.hasOwnProperty('defaultMaxRam')) {
134
+ const parsedRam = Number(settings.defaultMaxRam);
135
+ if (Number.isFinite(parsedRam) && parsedRam > 0) {
136
+ merged.defaultMaxRam = Math.floor(parsedRam);
137
+ }
138
+ }
139
+ if (settings.hasOwnProperty('discordRpcEnabled')) {
140
+ merged.discordRpcEnabled = Boolean(settings.discordRpcEnabled);
141
+ }
142
+ if (settings.hasOwnProperty('extensionsAutoUpdate')) {
143
+ merged.extensionsAutoUpdate = Boolean(settings.extensionsAutoUpdate);
144
+ }
145
+ if (settings.hasOwnProperty('disableSounds')) {
146
+ merged.disableSounds = Boolean(settings.disableSounds);
147
+ }
148
+ if (settings.hasOwnProperty('disableAutostart')) {
149
+ merged.disableAutostart = Boolean(settings.disableAutostart);
150
+ }
151
+ if (settings.hasOwnProperty('startInTray')) {
152
+ merged.startInTray = Boolean(settings.startInTray);
153
+ }
154
+ return merged;
155
+ } catch (error) {
156
+ console.error('Ошибка при загрузке настроек:', error);
157
+ return { ...DEFAULT_SETTINGS };
158
+ }
159
+ }
160
+
161
+ /**
162
+ * Сохранить настройки в файл
163
+ */
164
+ export function saveSettings(settings: LocalSettings): void {
165
+ if (!isNodeEnv || !fs || !path) {
166
+ console.warn(
167
+ 'Node.js окружение недоступно, настройки не могут быть сохранены',
168
+ );
169
+ return;
170
+ }
171
+
172
+ try {
173
+ const filePath = getSettingsFilePath();
174
+ const dirPath = path.dirname(filePath);
175
+
176
+ // Создаем директорию, если её нет
177
+ if (!fs.existsSync(dirPath)) {
178
+ fs.mkdirSync(dirPath, { recursive: true });
179
+ }
180
+
181
+ const settingsToSave: LocalSettings = {
182
+ ...settings,
183
+ version: STORAGE_VERSION,
184
+ };
185
+
186
+ fs.writeFileSync(
187
+ filePath,
188
+ JSON.stringify(settingsToSave, null, 2),
189
+ 'utf-8',
190
+ );
191
+ } catch (error) {
192
+ console.error('Ошибка при сохранении настроек:', error);
193
+ throw error;
194
+ }
195
+ }
196
+
197
+ /**
198
+ * Обновить конкретную настройку
199
+ */
200
+ export function updateSetting<K extends keyof LocalSettings>(
201
+ key: K,
202
+ value: LocalSettings[K],
203
+ ): void {
204
+ const settings = loadSettings();
205
+ settings[key] = value;
206
+ saveSettings(settings);
207
+ }
208
+
209
+ /**
210
+ * Получить конкретную настройку
211
+ */
212
+ export function getSetting<K extends keyof LocalSettings>(
213
+ key: K,
214
+ ): LocalSettings[K] {
215
+ const settings = loadSettings();
216
+ return settings[key] ?? DEFAULT_SETTINGS[key];
217
+ }
@@ -0,0 +1,35 @@
1
+ import type { DownloadDailyStatPoint } from '../api/download-stats';
2
+
3
+ function utcDateKey(date: Date): string {
4
+ return date.toISOString().slice(0, 10);
5
+ }
6
+
7
+ function normalizeDateKey(raw: string): string {
8
+ if (/^\d{4}-\d{2}-\d{2}$/.test(raw)) return raw;
9
+ return utcDateKey(new Date(raw));
10
+ }
11
+
12
+ /** Агрегирует даты присоединения участников в дневные точки { date, count }. */
13
+ export function buildMemberJoinDailyPoints(
14
+ members: Array<{ joinedAt?: string | null }>,
15
+ ): DownloadDailyStatPoint[] {
16
+ const byDate = new Map<string, number>();
17
+
18
+ for (const member of members) {
19
+ if (!member.joinedAt) continue;
20
+ const dateKey = normalizeDateKey(member.joinedAt);
21
+ byDate.set(dateKey, (byDate.get(dateKey) ?? 0) + 1);
22
+ }
23
+
24
+ return Array.from(byDate.entries()).map(([date, count]) => ({ date, count }));
25
+ }
26
+
27
+ export function filterDailyPointsInRange(
28
+ points: DownloadDailyStatPoint[],
29
+ range: { from: string; to: string },
30
+ ): DownloadDailyStatPoint[] {
31
+ return points.filter((point) => {
32
+ const dateKey = normalizeDateKey(point.date);
33
+ return dateKey >= range.from && dateKey <= range.to;
34
+ });
35
+ }
@@ -0,0 +1,86 @@
1
+ // Проверка на наличие Node.js окружения (NW.js)
2
+ const isNodeEnv = typeof window !== 'undefined' && (window as any).nw;
3
+
4
+ let os: any;
5
+ let path: any;
6
+
7
+ if (isNodeEnv) {
8
+ try {
9
+ const nw = (window as any).nw;
10
+ os = nw.require('os');
11
+ path = nw.require('path');
12
+ } catch (error) {
13
+ console.error('Не удалось загрузить Node.js модули:', error);
14
+ }
15
+ }
16
+
17
+ /**
18
+ * Определить платформу (win | linux | osx)
19
+ */
20
+ export function getPlatform(): 'win' | 'linux' | 'osx' {
21
+ if (!isNodeEnv || !os) {
22
+ // Fallback для браузерного окружения
23
+ const userAgent = navigator.userAgent.toLowerCase();
24
+ if (userAgent.includes('win')) return 'win';
25
+ if (userAgent.includes('mac') || userAgent.includes('darwin')) return 'osx';
26
+ return 'linux';
27
+ }
28
+
29
+ const platform = os.platform();
30
+ if (platform === 'win32') return 'win';
31
+ if (platform === 'darwin') return 'osx';
32
+ return 'linux';
33
+ }
34
+
35
+ /**
36
+ * Определить архитектуру (x64 | ia32 | arm64)
37
+ */
38
+ export function getArchitecture(): 'x64' | 'ia32' | 'arm64' {
39
+ if (!isNodeEnv || !os) {
40
+ // Fallback для браузерного окружения
41
+ return 'x64';
42
+ }
43
+
44
+ const arch = os.arch();
45
+ if (arch === 'x64' || arch === 'amd64') return 'x64';
46
+ if (arch === 'ia32' || arch === 'x32') return 'ia32';
47
+ if (arch === 'arm64') return 'arm64';
48
+
49
+ // По умолчанию x64
50
+ return 'x64';
51
+ }
52
+
53
+ /**
54
+ * Получить путь к исполняемому файлу приложения
55
+ */
56
+ export function getExecutablePath(): string | null {
57
+ if (!isNodeEnv || !path) {
58
+ return null;
59
+ }
60
+
61
+ try {
62
+ const nw = (window as any).nw;
63
+ // В NW.js можно получить путь к исполняемому файлу через process.execPath
64
+ // Но нужно учесть, что в dev режиме это может быть nw.exe, а в production - наш exe
65
+ const execPath = process.execPath;
66
+
67
+ // Получаем директорию, где находится исполняемый файл
68
+ return path.dirname(execPath);
69
+ } catch (error) {
70
+ console.error('Не удалось получить путь к исполняемому файлу:', error);
71
+ return null;
72
+ }
73
+ }
74
+
75
+ /**
76
+ * Получить путь к package.nw рядом с исполняемым файлом
77
+ */
78
+ export function getPackageNwPath(): string | null {
79
+ const execDir = getExecutablePath();
80
+ if (!execDir || !path) {
81
+ return null;
82
+ }
83
+
84
+ return path.join(execDir, 'package.nw');
85
+ }
86
+
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Поддомен play.*: только [a-z0-9_-]. Имя кодируется как `x` + hex(utf8).
3
+ * (base64url нельзя приводить к lower case — регистр значим.)
4
+ */
5
+
6
+ const SLUG_PREFIX = 'x';
7
+
8
+ export function encodePlayHostSlug(username: string): string {
9
+ const hex = Buffer.from(username.trim(), 'utf8').toString('hex').toLowerCase();
10
+ return `${SLUG_PREFIX}${hex}`;
11
+ }
12
+
13
+ export function decodePlayHostSlug(slug: string): string | null {
14
+ const normalized = slug.trim().toLowerCase();
15
+ if (!normalized.startsWith(SLUG_PREFIX)) return null;
16
+
17
+ const hex = normalized.slice(SLUG_PREFIX.length);
18
+ if (!hex || hex.length % 2 !== 0 || hex.length > 126) return null;
19
+ if (!/^[a-f0-9]+$/.test(hex)) return null;
20
+
21
+ try {
22
+ const decoded = Buffer.from(hex, 'hex').toString('utf8');
23
+ if (!decoded) return null;
24
+ if (encodePlayHostSlug(decoded) !== normalized) return null;
25
+ return decoded;
26
+ } catch {
27
+ return null;
28
+ }
29
+ }
30
+
31
+ export function buildPublicPlayHost(username: string, playDomain: string): string {
32
+ return `${encodePlayHostSlug(username)}.${playDomain}`;
33
+ }
34
+
35
+ /** host:port для Minecraft (порт по умолчанию 25565). */
36
+ export function formatPlayConnectAddress(
37
+ username: string,
38
+ playDomain: string,
39
+ port = 25565,
40
+ ): string {
41
+ return `${buildPublicPlayHost(username, playDomain)}:${port}`;
42
+ }
43
+
44
+ /**
45
+ * Для UI: если в БД остался сырой `{username}.play…`, пересобрать slug по нику владельца.
46
+ */
47
+ export function resolvePlayHostForDisplay(
48
+ host: string,
49
+ playDomain: string,
50
+ ownerUsername?: string | null,
51
+ ): string {
52
+ const hostOnly = host.split(':')[0]?.trim() ?? host;
53
+ if (playUsernameFromHostname(hostOnly, playDomain)) return hostOnly;
54
+ const owner = ownerUsername?.trim();
55
+ if (owner) return buildPublicPlayHost(owner, playDomain);
56
+ return hostOnly;
57
+ }
58
+
59
+ /** Slug из hostname (без порта), если суффикс совпадает с playDomain. */
60
+ export function playSlugFromHostname(
61
+ hostname: string,
62
+ playDomain: string,
63
+ ): string | null {
64
+ const host = hostname.split(':')[0]?.trim() ?? '';
65
+ if (!host) return null;
66
+ const suffix = `.${playDomain.toLowerCase()}`;
67
+ const lower = host.toLowerCase();
68
+ if (!lower.endsWith(suffix)) return null;
69
+ const slug = host.slice(0, host.length - suffix.length);
70
+ if (!slug || slug.includes('.')) return null;
71
+ return slug;
72
+ }
73
+
74
+ /**
75
+ * Username для поиска туннеля: декодированный `x…` slug или legacy label (a-z0-9-).
76
+ */
77
+ export function playUsernameFromHostname(
78
+ hostname: string,
79
+ playDomain: string,
80
+ ): string | null {
81
+ const slug = playSlugFromHostname(hostname, playDomain);
82
+ if (!slug) return null;
83
+
84
+ const decoded = decodePlayHostSlug(slug);
85
+ if (decoded) return decoded;
86
+
87
+ if (/^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?$/.test(slug)) {
88
+ return slug;
89
+ }
90
+
91
+ return null;
92
+ }