@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,439 @@
1
+ import type { BuildVersionManifest } from '../minecraft-types/build-manifest';
2
+ import { getBuildDirectory } from './local-mods';
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
+ export type FileCategory =
25
+ | 'included'
26
+ | 'ignored'
27
+ | 'selectable'
28
+ | 'unavailable';
29
+
30
+ /**
31
+ * Информация о файле в дереве файлов
32
+ */
33
+ export interface BuildFileInfo {
34
+ /**
35
+ * Путь относительно директории сборки
36
+ */
37
+ path: string;
38
+
39
+ /**
40
+ * Полный путь к файлу
41
+ */
42
+ fullPath: string;
43
+
44
+ /**
45
+ * Имя файла или директории
46
+ */
47
+ name: string;
48
+
49
+ /**
50
+ * Это директория?
51
+ */
52
+ isDirectory: boolean;
53
+
54
+ /**
55
+ * Размер файла в байтах (только для файлов)
56
+ */
57
+ size?: number;
58
+
59
+ /**
60
+ * Категория файла
61
+ */
62
+ category: FileCategory;
63
+
64
+ /**
65
+ * Выбран ли файл для включения в сборку
66
+ */
67
+ selected: boolean;
68
+
69
+ /**
70
+ * Пропускать проверку хеша при загрузке (для конфигов, которые игрок может редактировать)
71
+ */
72
+ skipHash?: boolean;
73
+
74
+ /**
75
+ * Дочерние элементы (для директорий)
76
+ */
77
+ children?: BuildFileInfo[];
78
+ }
79
+
80
+ /**
81
+ * Проверить, должен ли путь быть недоступен для выбора
82
+ */
83
+ function isUnavailablePath(filePath: string, fileName: string): boolean {
84
+ if (!path) return false;
85
+
86
+ // Директории и файлы, которые нельзя выбрать
87
+ const unavailableItems = [
88
+ 'saves',
89
+ '.fabric',
90
+ 'logs',
91
+ 'usercache.json',
92
+ 'downloads',
93
+ 'realms_persistence.json',
94
+ ];
95
+
96
+ // Проверяем имя файла/директории
97
+ if (unavailableItems.includes(fileName.toLowerCase())) {
98
+ return true;
99
+ }
100
+
101
+ // Проверяем путь (например, "saves/world1" тоже должен быть недоступен)
102
+ const normalizedPath = filePath.replace(/\\/g, '/').toLowerCase();
103
+ for (const unavailable of unavailableItems) {
104
+ if (
105
+ normalizedPath.startsWith(unavailable + '/') ||
106
+ normalizedPath === unavailable
107
+ ) {
108
+ return true;
109
+ }
110
+ }
111
+
112
+ return false;
113
+ }
114
+
115
+ /**
116
+ * Проверить, является ли путь игнорируемым по умолчанию
117
+ */
118
+ function isIgnoredPath(filePath: string, fileName: string): boolean {
119
+ if (!path) return false;
120
+
121
+ // Файлы с расширением .disabled
122
+ if (fileName.endsWith('.disabled')) {
123
+ return true;
124
+ }
125
+
126
+ // Директории, начинающиеся с "." (кроме .fabric, который уже в unavailable)
127
+ if (fileName.startsWith('.') && fileName !== '.fabric') {
128
+ return true;
129
+ }
130
+
131
+ // Конкретные файлы и директории для игнорирования
132
+ const ignoredItems = ['options.txt', 'defaultconfigs'];
133
+
134
+ // Проверяем имя файла/директории
135
+ if (ignoredItems.includes(fileName.toLowerCase())) {
136
+ return true;
137
+ }
138
+
139
+ // Проверяем путь (например, "saves/world1" тоже должен игнорироваться)
140
+ const normalizedPath = filePath.replace(/\\/g, '/').toLowerCase();
141
+ for (const ignored of ignoredItems) {
142
+ if (
143
+ normalizedPath.startsWith(ignored + '/') ||
144
+ normalizedPath === ignored
145
+ ) {
146
+ return true;
147
+ }
148
+ }
149
+
150
+ return false;
151
+ }
152
+
153
+ /**
154
+ * Проверить, является ли файл уже включенным в сборку
155
+ */
156
+ function isIncludedFile(
157
+ filePath: string,
158
+ fileName: string,
159
+ manifest: BuildVersionManifest | null,
160
+ ): boolean {
161
+ if (!manifest || !path) return false;
162
+
163
+ // version-manifest.json всегда включен
164
+ if (fileName === 'version-manifest.json') {
165
+ return true;
166
+ }
167
+
168
+ // <minecraftVersion>.jar всегда включен
169
+ const minecraftVersion = manifest._meta?.manifest?.minecraftVersion;
170
+ if (minecraftVersion && fileName === `${minecraftVersion}.jar`) {
171
+ return true;
172
+ }
173
+
174
+ // Проверяем моды
175
+ if (manifest.mods) {
176
+ for (const mod of manifest.mods) {
177
+ for (const file of mod.files || []) {
178
+ const modPath = file.path || `mods/${file.filename}`;
179
+ if (modPath === filePath || path.basename(modPath) === fileName) {
180
+ return true;
181
+ }
182
+ }
183
+ }
184
+ }
185
+
186
+ // Проверяем ресурспаки
187
+ if (manifest.resourcePacks) {
188
+ for (const rp of manifest.resourcePacks) {
189
+ for (const file of rp.files || []) {
190
+ const rpPath = file.path || `resourcepacks/${file.filename}`;
191
+ if (rpPath === filePath || path.basename(rpPath) === fileName) {
192
+ return true;
193
+ }
194
+ }
195
+ }
196
+ }
197
+
198
+ // Проверяем шейдеры
199
+ if (manifest.shaderPacks) {
200
+ for (const sp of manifest.shaderPacks) {
201
+ for (const file of sp.files || []) {
202
+ const spPath = file.path || `shaderpacks/${file.filename}`;
203
+ if (spPath === filePath || path.basename(spPath) === fileName) {
204
+ return true;
205
+ }
206
+ }
207
+ }
208
+ }
209
+
210
+ // versionAssets не проверяем - они формируются на беке из выбранных файлов
211
+
212
+ return false;
213
+ }
214
+
215
+ /**
216
+ * Рекурсивно сканировать директорию и построить дерево файлов
217
+ */
218
+ function scanDirectory(
219
+ dirPath: string,
220
+ relativePath: string,
221
+ manifest: BuildVersionManifest | null,
222
+ selectedFiles: Map<string, { skipHash?: boolean }>,
223
+ ): BuildFileInfo[] {
224
+ if (!isNodeEnv || !fs || !path) return [];
225
+
226
+ const files: BuildFileInfo[] = [];
227
+
228
+ try {
229
+ const entries = fs.readdirSync(dirPath, { withFileTypes: true });
230
+
231
+ for (const entry of entries) {
232
+ const fileName = entry.name;
233
+ const fullPath = path.join(dirPath, fileName);
234
+ const relativeFilePath = relativePath
235
+ ? `${relativePath}/${fileName}`
236
+ : fileName;
237
+
238
+ // Пропускаем version-manifest.json в корне (он уже включен)
239
+ if (relativePath === '' && fileName === 'version-manifest.json') {
240
+ continue;
241
+ }
242
+
243
+ const isDir = entry.isDirectory();
244
+ let size: number | undefined;
245
+ let category: FileCategory;
246
+ let children: BuildFileInfo[] | undefined;
247
+
248
+ if (isDir) {
249
+ // Рекурсивно сканируем поддиректорию
250
+ children = scanDirectory(
251
+ fullPath,
252
+ relativeFilePath,
253
+ manifest,
254
+ selectedFiles,
255
+ );
256
+ } else {
257
+ // Получаем размер файла
258
+ try {
259
+ const stats = fs.statSync(fullPath);
260
+ size = stats.size;
261
+ } catch (error) {
262
+ console.error(
263
+ `Ошибка при получении размера файла ${fullPath}:`,
264
+ error,
265
+ );
266
+ }
267
+ }
268
+
269
+ // Определяем категорию
270
+ if (isIncludedFile(relativeFilePath, fileName, manifest)) {
271
+ category = 'included';
272
+ } else if (isUnavailablePath(relativeFilePath, fileName)) {
273
+ category = 'unavailable';
274
+ } else if (isIgnoredPath(relativeFilePath, fileName)) {
275
+ category = 'ignored';
276
+ } else {
277
+ category = 'selectable';
278
+ }
279
+
280
+ // Проверяем, выбран ли файл
281
+ const selectedFileInfo = selectedFiles.get(relativeFilePath);
282
+ const selected = !!selectedFileInfo;
283
+ const skipHash = selectedFileInfo?.skipHash || false;
284
+
285
+ const fileInfo: BuildFileInfo = {
286
+ path: relativeFilePath,
287
+ fullPath,
288
+ name: fileName,
289
+ isDirectory: isDir,
290
+ size,
291
+ category,
292
+ selected,
293
+ skipHash: selected ? skipHash : undefined,
294
+ children: isDir ? children : undefined,
295
+ };
296
+
297
+ files.push(fileInfo);
298
+ }
299
+ } catch (error) {
300
+ console.error(`Ошибка при сканировании директории ${dirPath}:`, error);
301
+ }
302
+
303
+ // Сортируем: сначала директории, потом файлы, по алфавиту
304
+ files.sort((a, b) => {
305
+ if (a.isDirectory !== b.isDirectory) {
306
+ return a.isDirectory ? -1 : 1;
307
+ }
308
+ return a.name.localeCompare(b.name);
309
+ });
310
+
311
+ return files;
312
+ }
313
+
314
+ /**
315
+ * Сканировать файлы сборки и построить дерево
316
+ */
317
+ export function scanBuildFiles(
318
+ buildId: string,
319
+ manifest: BuildVersionManifest | null,
320
+ explicitBuildDir?: string,
321
+ ): BuildFileInfo[] {
322
+ if (!isNodeEnv || !fs || !path) {
323
+ throw new Error('Node.js окружение недоступно');
324
+ }
325
+
326
+ // Если сборка еще не сохранена (ID = '_new'), возвращаем пустой массив
327
+ // Файлы появятся только после первого сохранения
328
+ if (!buildId || buildId === '_new') {
329
+ return [];
330
+ }
331
+
332
+ const buildDir = explicitBuildDir || getBuildDirectory(buildId);
333
+ if (!buildDir) {
334
+ throw new Error('Не удалось получить путь к директории сборки');
335
+ }
336
+
337
+ const dirExists = fs.existsSync(buildDir);
338
+ if (!dirExists) {
339
+ // Если директория не существует, возвращаем пустой массив вместо ошибки
340
+ // Это может произойти, если сборка еще не была сохранена
341
+ return [];
342
+ }
343
+
344
+ try {
345
+ // Проверяем, что это директория
346
+ const stats = fs.statSync(buildDir);
347
+ if (!stats.isDirectory()) {
348
+ throw new Error(`Путь не является директорией: ${buildDir}`);
349
+ }
350
+ } catch (error) {
351
+ throw new Error(
352
+ `Ошибка при доступе к директории ${buildDir}: ${error instanceof Error ? error.message : 'Неизвестная ошибка'}`,
353
+ );
354
+ }
355
+
356
+ // Преобразуем selectedFiles из массива объектов в Map для быстрого доступа
357
+ const selectedFiles = new Map<string, { skipHash?: boolean }>();
358
+ if (manifest?.selectedFiles) {
359
+ for (const file of manifest.selectedFiles) {
360
+ if (typeof file === 'string') {
361
+ // Поддержка старого формата (массив строк) для обратной совместимости
362
+ selectedFiles.set(file, {});
363
+ } else {
364
+ selectedFiles.set(file.path, { skipHash: file.skipHash });
365
+ }
366
+ }
367
+ }
368
+
369
+ // Сканируем директорию
370
+ return scanDirectory(buildDir, '', manifest, selectedFiles);
371
+ }
372
+
373
+ /**
374
+ * Вычислить общий размер выбранных файлов
375
+ */
376
+ export function calculateSelectedFilesSize(files: BuildFileInfo[]): number {
377
+ let totalSize = 0;
378
+
379
+ function traverse(fileList: BuildFileInfo[]) {
380
+ for (const file of fileList) {
381
+ if (file.selected && !file.isDirectory && file.size) {
382
+ totalSize += file.size;
383
+ }
384
+ if (file.children) {
385
+ traverse(file.children);
386
+ }
387
+ }
388
+ }
389
+
390
+ traverse(files);
391
+ return totalSize;
392
+ }
393
+
394
+ /**
395
+ * Подсчитать количество выбранных файлов
396
+ */
397
+ export function countSelectedFiles(files: BuildFileInfo[]): number {
398
+ let count = 0;
399
+
400
+ function traverse(fileList: BuildFileInfo[]) {
401
+ for (const file of fileList) {
402
+ if (file.selected && !file.isDirectory) {
403
+ count++;
404
+ }
405
+ if (file.children) {
406
+ traverse(file.children);
407
+ }
408
+ }
409
+ }
410
+
411
+ traverse(files);
412
+ return count;
413
+ }
414
+
415
+ /**
416
+ * Получить все выбранные файлы из дерева файлов
417
+ */
418
+ export function getSelectedPaths(
419
+ files: BuildFileInfo[],
420
+ ): Array<{ path: string; skipHash?: boolean }> {
421
+ const result: Array<{ path: string; skipHash?: boolean }> = [];
422
+
423
+ function traverse(fileList: BuildFileInfo[]) {
424
+ for (const file of fileList) {
425
+ if (file.selected && !file.isDirectory) {
426
+ result.push({
427
+ path: file.path,
428
+ skipHash: file.skipHash || undefined,
429
+ });
430
+ }
431
+ if (file.children) {
432
+ traverse(file.children);
433
+ }
434
+ }
435
+ }
436
+
437
+ traverse(files);
438
+ return result;
439
+ }
@@ -0,0 +1,176 @@
1
+ import type { BuildVersionManifest } from '../minecraft-types/build-manifest';
2
+ import { cloneDeep } from 'lodash-es';
3
+
4
+ /**
5
+ * Эталонный минимальный манифест сборки
6
+ */
7
+ export function getDefaultBuildManifest(
8
+ uuid: string,
9
+ name: string = 'Новая сборка',
10
+ ): BuildVersionManifest {
11
+ const now = new Date().toISOString();
12
+ return {
13
+ id: uuid,
14
+ type: 'release',
15
+ arguments: {
16
+ game: [],
17
+ jvm: [],
18
+ },
19
+ libraries: [],
20
+ _meta: {
21
+ uuid: '',
22
+ name: name,
23
+ version: '0.0.0',
24
+ releaseTime: now,
25
+ time: now,
26
+ settings: {
27
+ javaPath: '',
28
+ jvmArgs: '',
29
+ maxRam: 2048,
30
+ },
31
+ manifest: {
32
+ minecraftVersion: '',
33
+ loader: 'vanilla',
34
+ loaderVersion: '',
35
+ },
36
+ description: '',
37
+ image: '',
38
+ stats: {
39
+ lastPlayed: '',
40
+ playTime: 0,
41
+ },
42
+ author: {
43
+ id: '',
44
+ username: '',
45
+ name: '',
46
+ },
47
+ },
48
+ versionAssets: [],
49
+ mods: [],
50
+ resourcePacks: [],
51
+ shaderPacks: [],
52
+ selectedFiles: [],
53
+ };
54
+ }
55
+
56
+ /**
57
+ * Инициализировать манифест сборки, мержа эталонный манифест с существующими данными
58
+ * @param existingManifest Существующий манифест (если есть)
59
+ * @param uuid UUID сборки
60
+ * @param name Название сборки
61
+ * @returns Инициализированный манифест
62
+ */
63
+ export function initializeBuildManifest(
64
+ existingManifest: BuildVersionManifest | null,
65
+ uuid?: string,
66
+ name?: string,
67
+ ): BuildVersionManifest {
68
+ // Создаем эталонный манифест
69
+ const defaultManifest = getDefaultBuildManifest(
70
+ uuid || '',
71
+ name || existingManifest?._meta?.name || 'Новая сборка',
72
+ );
73
+
74
+ if (!existingManifest) {
75
+ // Если манифеста нет, возвращаем эталонный
76
+ return cloneDeep(defaultManifest);
77
+ }
78
+
79
+ // Клонируем существующий манифест, чтобы не изменять оригинал
80
+ const manifest = cloneDeep(existingManifest);
81
+
82
+ // Мержим _meta, сохраняя существующие данные
83
+ if (!manifest._meta) {
84
+ manifest._meta = cloneDeep(defaultManifest._meta);
85
+ } else {
86
+ // Мержим поля _meta, сохраняя существующие значения
87
+ const defaultMeta = defaultManifest._meta!;
88
+
89
+ // Убеждаемся, что обязательные поля существуют
90
+ if (!manifest._meta.uuid) {
91
+ manifest._meta.uuid = defaultMeta.uuid;
92
+ }
93
+ if (!manifest._meta.name) {
94
+ manifest._meta.name = defaultMeta.name;
95
+ }
96
+ if (!manifest._meta.version) {
97
+ manifest._meta.version = defaultMeta.version;
98
+ }
99
+ if (!manifest._meta.releaseTime) {
100
+ manifest._meta.releaseTime = defaultMeta.releaseTime;
101
+ }
102
+ if (!manifest._meta.time) {
103
+ manifest._meta.time = defaultMeta.time;
104
+ }
105
+
106
+ // Мержим settings
107
+ if (!manifest._meta.settings) {
108
+ manifest._meta.settings = cloneDeep(defaultMeta.settings);
109
+ } else {
110
+ // Убеждаемся, что все поля settings существуют
111
+ if (manifest._meta.settings.javaPath === undefined) {
112
+ manifest._meta.settings.javaPath = defaultMeta.settings!.javaPath;
113
+ }
114
+ if (manifest._meta.settings.jvmArgs === undefined) {
115
+ manifest._meta.settings.jvmArgs = defaultMeta.settings!.jvmArgs;
116
+ }
117
+ if (manifest._meta.settings.maxRam === undefined) {
118
+ manifest._meta.settings.maxRam = defaultMeta.settings!.maxRam;
119
+ }
120
+ }
121
+
122
+ // Мержим manifest (информация о версии Minecraft и загрузчике)
123
+ if (!manifest._meta.manifest) {
124
+ manifest._meta.manifest = cloneDeep(defaultMeta.manifest);
125
+ } else {
126
+ // Убеждаемся, что все поля manifest существуют
127
+ // НЕ перезаписываем, если поле уже заполнено пользователем (не пустое и не undefined)
128
+ if (manifest._meta.manifest.minecraftVersion === undefined) {
129
+ manifest._meta.manifest.minecraftVersion =
130
+ defaultMeta.manifest!.minecraftVersion;
131
+ }
132
+ // Если поле пустое (''), НЕ перезаписываем его дефолтным значением - это может быть намеренно
133
+ // Но если undefined, используем дефолтное значение
134
+ if (manifest._meta.manifest.loader === undefined) {
135
+ manifest._meta.manifest.loader = defaultMeta.manifest!.loader;
136
+ }
137
+ if (manifest._meta.manifest.loaderVersion === undefined) {
138
+ manifest._meta.manifest.loaderVersion =
139
+ defaultMeta.manifest!.loaderVersion;
140
+ }
141
+ }
142
+ }
143
+
144
+ // Убеждаемся, что основные поля манифеста существуют
145
+ if (!manifest.id) {
146
+ manifest.id = defaultManifest.id;
147
+ }
148
+ if (!manifest.type) {
149
+ manifest.type = defaultManifest.type;
150
+ }
151
+ if (!manifest.arguments) {
152
+ manifest.arguments = cloneDeep(defaultManifest.arguments);
153
+ }
154
+ if (!manifest.libraries) {
155
+ manifest.libraries = cloneDeep(defaultManifest.libraries);
156
+ }
157
+ // Сохраняем существующие mods и resourcePacks, если они есть
158
+ if (!manifest.mods) {
159
+ manifest.mods = [];
160
+ }
161
+ if (!manifest.resourcePacks) {
162
+ manifest.resourcePacks = [];
163
+ }
164
+ if (!manifest.shaderPacks) {
165
+ manifest.shaderPacks = [];
166
+ }
167
+ if (!manifest.versionAssets) {
168
+ manifest.versionAssets = [];
169
+ }
170
+ // Инициализируем selectedFiles, если его нет
171
+ if (!manifest.selectedFiles) {
172
+ manifest.selectedFiles = [];
173
+ }
174
+
175
+ return manifest;
176
+ }
@@ -0,0 +1,67 @@
1
+ export interface CloudinaryTransformOptions {
2
+ width?: number;
3
+ height?: number;
4
+ crop?: 'limit' | 'fill' | 'fit' | 'scale' | 'thumb' | 'crop';
5
+ quality?: number | 'auto';
6
+ format?: 'auto' | 'webp' | 'jpg' | 'png';
7
+ gravity?: 'auto' | 'face' | 'center';
8
+ }
9
+
10
+ /**
11
+ * Добавляет трансформации Cloudinary к URL изображения
12
+ * @param url Оригинальный URL от Cloudinary
13
+ * @param options Параметры трансформации
14
+ * @returns URL с трансформациями
15
+ */
16
+ export function transformCloudinaryUrl(
17
+ url: string | undefined | null,
18
+ options: CloudinaryTransformOptions
19
+ ): string {
20
+ if (!url || !url.includes('cloudinary.com')) {
21
+ return url || ''; // Возвращаем оригинальный URL если это не Cloudinary
22
+ }
23
+
24
+ const transformations: string[] = [];
25
+
26
+ if (options.width) {
27
+ transformations.push(`w_${options.width}`);
28
+ }
29
+ if (options.height) {
30
+ transformations.push(`h_${options.height}`);
31
+ }
32
+ if (options.crop) {
33
+ transformations.push(`c_${options.crop}`);
34
+ } else if (options.width || options.height) {
35
+ // По умолчанию используем limit если указаны размеры
36
+ transformations.push('c_limit');
37
+ }
38
+ if (options.quality) {
39
+ transformations.push(`q_${options.quality}`);
40
+ } else {
41
+ // Автоматическое качество по умолчанию
42
+ transformations.push('q_auto');
43
+ }
44
+ if (options.format) {
45
+ transformations.push(`f_${options.format}`);
46
+ } else {
47
+ // Автоматический формат по умолчанию
48
+ transformations.push('f_auto');
49
+ }
50
+ if (options.gravity) {
51
+ transformations.push(`g_${options.gravity}`);
52
+ }
53
+
54
+ if (transformations.length === 0) {
55
+ return url;
56
+ }
57
+
58
+ const transformString = transformations.join(',');
59
+
60
+ // Вставляем трансформации между /upload/ и версией/путем
61
+ // Формат: https://res.cloudinary.com/{cloud}/image/upload/{transformations}/{version}/{path}
62
+ return url.replace(
63
+ /\/upload\/(v\d+\/)?/,
64
+ `/upload/${transformString}/$1`
65
+ );
66
+ }
67
+
@@ -0,0 +1,7 @@
1
+ import { type ClassValue, clsx } from 'clsx';
2
+ import { twMerge } from 'tailwind-merge';
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs));
6
+ }
7
+