@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,372 @@
1
+ /**
2
+ * Утилиты для работы с кешем рендеров скинов Minecraft
3
+ */
4
+
5
+ import axios from 'axios';
6
+
7
+ import { getAppDataPath } from './app-paths';
8
+
9
+ /** Параметры 3D-рендера (совместимы с пакетом `@rynt/minecraft-skin-renderer`). */
10
+ export interface SkinRender3DOptions {
11
+ zoom?: number;
12
+ slim?: boolean;
13
+ rotationY?: number;
14
+ rotationX?: number;
15
+ }
16
+
17
+ export type SkinRender3DFn = (
18
+ source: string | Buffer,
19
+ options?: SkinRender3DOptions,
20
+ ) => Promise<Blob>;
21
+
22
+ let skinRenderImpl: SkinRender3DFn | null = null;
23
+
24
+ /**
25
+ * Подключение реализации рендера из хост-приложения (`@rynt/minecraft-skin-renderer`).
26
+ * SDK сам не зависит от пакета рендера.
27
+ */
28
+ export function configureRyntSkinRenderer(fn: SkinRender3DFn): void {
29
+ skinRenderImpl = fn;
30
+ }
31
+
32
+ async function invokeSkinRender(
33
+ renderSource: string | Buffer,
34
+ options?: SkinRender3DOptions,
35
+ ): Promise<Blob> {
36
+ if (!skinRenderImpl) {
37
+ throw new Error(
38
+ 'Skin renderer not configured: call configureRyntSkinRenderer() from the host.',
39
+ );
40
+ }
41
+ return skinRenderImpl(renderSource, options);
42
+ }
43
+
44
+ /**
45
+ * Получить SHA1 хеш от URL скина или локального файла
46
+ */
47
+ export async function getSkinSha1(skinUrl: string): Promise<string> {
48
+ // Проверяем, что мы в NW.js окружении
49
+ if (typeof window === 'undefined' || !(window as any).nw) {
50
+ throw new Error('Skin operations are only available in NW.js environment');
51
+ }
52
+
53
+ const nw = (window as any).nw;
54
+ const crypto = nw.require('crypto');
55
+ const Buffer = nw.require('buffer').Buffer;
56
+ const fs = nw.require('fs');
57
+ const path = nw.require('path');
58
+
59
+ let skinBuffer: Buffer;
60
+
61
+ // Проверяем, является ли URL локальным файлом
62
+ const isHttpUrl =
63
+ skinUrl.startsWith('http://') || skinUrl.startsWith('https://');
64
+ const isFileUrl = skinUrl.startsWith('file://');
65
+ const isRelativePath = skinUrl.startsWith('./') || skinUrl.startsWith('/');
66
+
67
+ if (isHttpUrl) {
68
+ // Скачиваем скин через HTTP
69
+ const response = await axios.get(skinUrl, {
70
+ responseType: 'arraybuffer',
71
+ });
72
+ skinBuffer = Buffer.from(response.data);
73
+ } else if (isFileUrl || isRelativePath) {
74
+ // Читаем локальный файл
75
+ let filePath: string;
76
+ if (isFileUrl) {
77
+ // Преобразуем file:// URL в путь
78
+ filePath = skinUrl.replace(/^file:\/\//, '').replace(/^\//, '');
79
+ // В Windows убираем лишний слеш после file:///
80
+ if (process.platform === 'win32' && filePath.match(/^[A-Za-z]:/)) {
81
+ // Уже правильный путь
82
+ } else {
83
+ filePath = filePath.replace(/^\//, '');
84
+ }
85
+ } else {
86
+ // Относительный путь - разрешаем относительно public директории
87
+ // В NW.js public директория может быть в process.cwd() или в process.cwd()/public
88
+ const cwd = process.cwd();
89
+ const relativePath = skinUrl.replace(/^\.\//, '');
90
+
91
+ // Пробуем несколько вариантов пути
92
+ const possiblePaths = [
93
+ path.join(cwd, relativePath), // Если cwd уже в public
94
+ path.join(cwd, 'public', relativePath), // Если cwd в packages/client
95
+ path.resolve(cwd, 'public', relativePath), // Абсолютный путь
96
+ ];
97
+
98
+ // Проверяем, какой путь существует
99
+ let foundPath: string | null = null;
100
+ for (const possiblePath of possiblePaths) {
101
+ try {
102
+ if (fs.existsSync(possiblePath)) {
103
+ foundPath = possiblePath;
104
+ break;
105
+ }
106
+ } catch {
107
+ // Игнорируем ошибки проверки
108
+ }
109
+ }
110
+
111
+ if (foundPath) {
112
+ filePath = foundPath;
113
+ } else {
114
+ // Если ни один путь не найден, используем первый вариант
115
+ filePath = path.join(cwd, 'public', relativePath);
116
+ }
117
+ }
118
+
119
+ // Читаем файл синхронно
120
+ skinBuffer = fs.readFileSync(filePath);
121
+ } else {
122
+ throw new Error(`Invalid skin URL: ${skinUrl}`);
123
+ }
124
+
125
+ // Вычисляем SHA1
126
+ const hash = crypto.createHash('sha1');
127
+ hash.update(skinBuffer);
128
+ return hash.digest('hex');
129
+ }
130
+
131
+ /**
132
+ * Получить путь к файлу рендера в кеше
133
+ */
134
+ export function getRenderCachePath(sha1: string): string {
135
+ if (typeof window === 'undefined' || !(window as any).nw) {
136
+ throw new Error('File operations are only available in NW.js environment');
137
+ }
138
+
139
+ const nw = (window as any).nw;
140
+ const path = nw.require('path');
141
+
142
+ const firstTwoChars = sha1.substring(0, 2);
143
+ const cacheDir = path.join(
144
+ getAppDataPath(),
145
+ 'assets',
146
+ 'skin-renders',
147
+ firstTwoChars,
148
+ );
149
+ const renderPath = path.join(cacheDir, `${sha1}.png`);
150
+
151
+ return renderPath;
152
+ }
153
+
154
+ /**
155
+ * Проверить, существует ли рендер в кеше
156
+ */
157
+ export async function isRenderCached(sha1: string): Promise<boolean> {
158
+ if (typeof window === 'undefined' || !(window as any).nw) {
159
+ return false;
160
+ }
161
+
162
+ const nw = (window as any).nw;
163
+ const fs = nw.require('fs');
164
+
165
+ const renderPath = getRenderCachePath(sha1);
166
+
167
+ return new Promise((resolve) => {
168
+ fs.access(renderPath, fs.constants.F_OK, (err: Error | null) => {
169
+ resolve(!err);
170
+ });
171
+ });
172
+ }
173
+
174
+ /**
175
+ * Получить путь к рендеру из кеша (file:// URL для использования в img src)
176
+ */
177
+ export function getRenderCacheUrl(sha1: string): string {
178
+ const renderPath = getRenderCachePath(sha1);
179
+ // Преобразуем путь в file:// URL
180
+ const normalizedPath = renderPath.replace(/\\/g, '/');
181
+ // В Windows пути начинаются с буквы диска (C:/), в Unix - с /
182
+ if (normalizedPath.match(/^[A-Za-z]:/)) {
183
+ // Windows путь
184
+ return `file:///${normalizedPath}`;
185
+ }
186
+ // Unix путь
187
+ return `file://${normalizedPath}`;
188
+ }
189
+
190
+ /**
191
+ * Рендерить скин и сохранить в кеш
192
+ */
193
+ export async function renderAndCacheSkin(
194
+ skinUrl: string,
195
+ sha1: string,
196
+ options?: {
197
+ zoom?: number;
198
+ slim?: boolean;
199
+ rotationY?: number;
200
+ rotationX?: number;
201
+ },
202
+ ): Promise<string> {
203
+ if (typeof window === 'undefined' || !(window as any).nw) {
204
+ throw new Error('Skin rendering is only available in NW.js environment');
205
+ }
206
+
207
+ const nw = (window as any).nw;
208
+ const fs = nw.require('fs');
209
+ const path = nw.require('path');
210
+
211
+ // Определяем тип источника
212
+ const isHttpUrl =
213
+ skinUrl.startsWith('http://') || skinUrl.startsWith('https://');
214
+ const isFileUrl = skinUrl.startsWith('file://');
215
+
216
+ // Для локальных файлов читаем их в Buffer, чтобы создать Blob URL (file:// не работает в браузере)
217
+ let renderSource: string | Buffer;
218
+ if (!isHttpUrl) {
219
+ // Локальный файл - читаем в Buffer
220
+ let filePath: string;
221
+ if (isFileUrl) {
222
+ // Преобразуем file:// URL в путь
223
+ filePath = skinUrl.replace(/^file:\/\//, '').replace(/^\//, '');
224
+ // В Windows убираем лишний слеш после file:///
225
+ if (process.platform === 'win32' && filePath.match(/^[A-Za-z]:/)) {
226
+ // Уже правильный путь
227
+ } else {
228
+ filePath = filePath.replace(/^\//, '');
229
+ }
230
+ } else {
231
+ // Относительный путь - разрешаем относительно public директории
232
+ // В NW.js public директория может быть в process.cwd() или в process.cwd()/public
233
+ const cwd = process.cwd();
234
+ const relativePath = skinUrl.replace(/^\.\//, '');
235
+
236
+ // Пробуем несколько вариантов пути
237
+ const possiblePaths = [
238
+ path.join(cwd, relativePath), // Если cwd уже в public
239
+ path.join(cwd, 'public', relativePath), // Если cwd в packages/client
240
+ path.resolve(cwd, 'public', relativePath), // Абсолютный путь
241
+ ];
242
+
243
+ // Проверяем, какой путь существует
244
+ let foundPath: string | null = null;
245
+ for (const possiblePath of possiblePaths) {
246
+ try {
247
+ if (fs.existsSync(possiblePath)) {
248
+ foundPath = possiblePath;
249
+ break;
250
+ }
251
+ } catch {
252
+ // Игнорируем ошибки проверки
253
+ }
254
+ }
255
+
256
+ if (foundPath) {
257
+ filePath = foundPath;
258
+ } else {
259
+ // Если ни один путь не найден, используем первый вариант
260
+ filePath = path.join(cwd, 'public', relativePath);
261
+ }
262
+ }
263
+
264
+ // Читаем файл в Buffer
265
+ renderSource = fs.readFileSync(filePath);
266
+ } else {
267
+ // HTTP URL - передаем как есть
268
+ renderSource = skinUrl;
269
+ }
270
+
271
+ // Рендерим скин (теперь возвращает Blob)
272
+ let renderBlob: Blob;
273
+ try {
274
+ renderBlob = await invokeSkinRender(renderSource, {
275
+ zoom: options?.zoom ?? 1.0,
276
+ slim: options?.slim ?? false,
277
+ rotationY: options?.rotationY ?? 45, // Изометрический вид сбоку
278
+ rotationX: options?.rotationX ?? 30, // Наклон сверху для изометрии
279
+ });
280
+ } catch (error) {
281
+ console.error('[Skin Render Cache] Error during invokeSkinRender:', error);
282
+ throw error;
283
+ }
284
+
285
+ // Конвертируем Blob в Buffer для сохранения
286
+ const arrayBuffer = await renderBlob.arrayBuffer();
287
+ const renderBuffer = Buffer.from(arrayBuffer);
288
+
289
+ // Создаем директорию для кеша, если её нет
290
+ const renderPath = getRenderCachePath(sha1);
291
+ const cacheDir = path.dirname(renderPath);
292
+
293
+ // Создаем директорию рекурсивно
294
+ await new Promise<void>((resolve, reject) => {
295
+ // Проверяем, существует ли директория
296
+ fs.stat(cacheDir, (err: Error | null) => {
297
+ if (err) {
298
+ // Директория не существует, создаем её
299
+ fs.mkdir(cacheDir, { recursive: true }, (mkdirErr: Error | null) => {
300
+ if (mkdirErr) {
301
+ reject(mkdirErr);
302
+ } else {
303
+ resolve();
304
+ }
305
+ });
306
+ } else {
307
+ resolve();
308
+ }
309
+ });
310
+ });
311
+
312
+ // Сохраняем рендер
313
+ await new Promise<void>((resolve, reject) => {
314
+ fs.writeFile(renderPath, renderBuffer, (err: Error | null) => {
315
+ if (err) {
316
+ console.error('[Skin Render Cache] Error saving render:', err);
317
+ reject(err);
318
+ } else {
319
+ // Проверяем, что файл действительно создан
320
+ fs.stat(renderPath, (statErr: Error | null) => {
321
+ if (statErr) {
322
+ console.error(
323
+ '[Skin Render Cache] Error verifying saved file:',
324
+ statErr,
325
+ );
326
+ reject(statErr);
327
+ } else {
328
+ resolve();
329
+ }
330
+ });
331
+ }
332
+ });
333
+ });
334
+
335
+ return getRenderCacheUrl(sha1);
336
+ }
337
+
338
+ /**
339
+ * Получить рендер скина (с кешированием)
340
+ * Возвращает file:// URL для использования в img src
341
+ */
342
+ export async function getSkinRender(
343
+ skinUrl: string,
344
+ sha1?: string,
345
+ options?: {
346
+ zoom?: number;
347
+ slim?: boolean;
348
+ rotationY?: number;
349
+ rotationX?: number;
350
+ },
351
+ ): Promise<string> {
352
+ try {
353
+ // Если sha1 не передан, вычисляем его
354
+ let skinSha1 = sha1;
355
+ if (!skinSha1) {
356
+ skinSha1 = await getSkinSha1(skinUrl);
357
+ }
358
+
359
+ // Проверяем кеш
360
+ const isCached = await isRenderCached(skinSha1);
361
+ if (isCached) {
362
+ return getRenderCacheUrl(skinSha1);
363
+ }
364
+
365
+ // Рендерим и кешируем
366
+ const renderUrl = await renderAndCacheSkin(skinUrl, skinSha1, options);
367
+ return renderUrl;
368
+ } catch (error) {
369
+ console.error('[Skin Render] Error during rendering:', error);
370
+ throw error;
371
+ }
372
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Удаляет markdown форматирование из текста
3
+ */
4
+ export function stripMarkdown(text: string): string {
5
+ if (!text) return '';
6
+
7
+ const withoutHtml = text
8
+ // Удаляем HTML-теги (для нового формата описаний)
9
+ .replace(/<[^>]*>/g, ' ')
10
+ .replace(/&nbsp;/gi, ' ')
11
+ .replace(/&amp;/gi, '&')
12
+ .replace(/&lt;/gi, '<')
13
+ .replace(/&gt;/gi, '>');
14
+
15
+ return withoutHtml
16
+ // Удаляем заголовки
17
+ .replace(/^#{1,6}\s+/gm, '')
18
+ // Удаляем жирный текст
19
+ .replace(/\*\*([^*]+)\*\*/g, '$1')
20
+ .replace(/__([^_]+)__/g, '$1')
21
+ // Удаляем курсив
22
+ .replace(/\*([^*]+)\*/g, '$1')
23
+ .replace(/_([^_]+)_/g, '$1')
24
+ // Удаляем зачеркнутый текст
25
+ .replace(/~~([^~]+)~~/g, '$1')
26
+ // Удаляем код
27
+ .replace(/`([^`]+)`/g, '$1')
28
+ .replace(/```[\s\S]*?```/g, '')
29
+ // Удаляем ссылки
30
+ .replace(/\[([^\]]+)\]\([^)]+\)/g, '$1')
31
+ // Удаляем изображения
32
+ .replace(/!\[([^\]]*)\]\([^)]+\)/g, '')
33
+ // Удаляем списки
34
+ .replace(/^[\s]*[-*+]\s+/gm, '')
35
+ .replace(/^[\s]*\d+\.\s+/gm, '')
36
+ // Удаляем цитаты
37
+ .replace(/^>\s+/gm, '')
38
+ // Удаляем горизонтальные линии
39
+ .replace(/^[-*]{3,}$/gm, '')
40
+ // Убираем лишние пробелы
41
+ .replace(/[ \t]{2,}/g, ' ')
42
+ .replace(/\n{3,}/g, '\n\n')
43
+ .trim();
44
+ }
45
+
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Транслитерация кириллицы в латиницу для генерации ID из имени
3
+ */
4
+ const transliterationMap: Record<string, string> = {
5
+ а: 'a',
6
+ б: 'b',
7
+ в: 'v',
8
+ г: 'g',
9
+ д: 'd',
10
+ е: 'e',
11
+ ё: 'e',
12
+ ж: 'zh',
13
+ з: 'z',
14
+ и: 'i',
15
+ й: 'y',
16
+ к: 'k',
17
+ л: 'l',
18
+ м: 'm',
19
+ н: 'n',
20
+ о: 'o',
21
+ п: 'p',
22
+ р: 'r',
23
+ с: 's',
24
+ т: 't',
25
+ у: 'u',
26
+ ф: 'f',
27
+ х: 'h',
28
+ ц: 'ts',
29
+ ч: 'ch',
30
+ ш: 'sh',
31
+ щ: 'shch',
32
+ ъ: '',
33
+ ы: 'y',
34
+ ь: '',
35
+ э: 'e',
36
+ ю: 'yu',
37
+ я: 'ya',
38
+ };
39
+
40
+ /**
41
+ * Генерирует ID из имени сборки через транслитерацию
42
+ * Пробелы заменяются на дефисы, все приводится к lowercase
43
+ */
44
+ export function generateBuildId(name: string): string {
45
+ if (!name) return '';
46
+
47
+ let result = name
48
+ .toLowerCase()
49
+ .split('')
50
+ .map((char) => {
51
+ // Если это кириллица, транслитерируем
52
+ if (transliterationMap[char]) {
53
+ return transliterationMap[char];
54
+ }
55
+ // Если это латиница или цифра, оставляем как есть
56
+ if (/[a-z0-9]/.test(char)) {
57
+ return char;
58
+ }
59
+ // Пробелы и другие символы заменяем на дефис
60
+ if (/\s/.test(char)) {
61
+ return '-';
62
+ }
63
+ // Остальные символы удаляем
64
+ return '';
65
+ })
66
+ .join('')
67
+ // Убираем множественные дефисы
68
+ .replace(/-+/g, '-')
69
+ // Убираем дефисы в начале и конце
70
+ .replace(/^-+|-+$/g, '');
71
+
72
+ return result || 'build';
73
+ }
74
+
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Утилита для обновления рендера скина аккаунта
3
+ */
4
+
5
+ import type { Account } from '@/models/accounts/types';
6
+ import { getSkinSha1 } from './skin-render-cache';
7
+
8
+ /**
9
+ * Обновить рендер скина для одного аккаунта
10
+ * Получает URL скина от провайдера, вычисляет SHA1 и обновляет профиль аккаунта
11
+ *
12
+ * @param account - Аккаунт для обновления
13
+ * @param provider - Провайдер аккаунта
14
+ * @param defaultSkinUrl - URL дефолтного скина, если у аккаунта нет скина
15
+ * @returns Обновленный профиль с skinUrl и skinSha1, или null если обновление не требуется
16
+ */
17
+ export async function updateAccountSkinRender(
18
+ account: Account,
19
+ provider: { getSkinUrl?: (account: Account) => Promise<string | null> | string | null; getProfile?: (account: Account) => Promise<any> },
20
+ defaultSkinUrl: string = './assets/image/steve_skin.png'
21
+ ): Promise<{ skinUrl: string; skinSha1: string | null } | null> {
22
+ try {
23
+ // Получаем скин от провайдера
24
+ let skinUrl: string | null = null;
25
+ if (provider.getSkinUrl) {
26
+ skinUrl = await provider.getSkinUrl(account);
27
+ } else if (provider.getProfile) {
28
+ const updatedProfile = await provider.getProfile(account);
29
+ skinUrl = updatedProfile.skinUrl || null;
30
+ }
31
+
32
+ // Если нет скина, подставляем дефолтный
33
+ if (!skinUrl) {
34
+ skinUrl = defaultSkinUrl;
35
+ }
36
+
37
+ // Вычисляем SHA1 скина, если он изменился
38
+ let skinSha1: string | null = null;
39
+ if (skinUrl !== account.profile?.skinUrl) {
40
+ try {
41
+ skinSha1 = await getSkinSha1(skinUrl);
42
+ } catch (error) {
43
+ console.debug('Failed to get skin SHA1:', error);
44
+ }
45
+ } else {
46
+ // Если URL не изменился, используем существующий SHA1
47
+ skinSha1 = account.profile?.skinSha1 || null;
48
+ }
49
+
50
+ // Возвращаем обновленные данные, если они изменились
51
+ if (skinUrl !== account.profile?.skinUrl || skinSha1 !== account.profile?.skinSha1) {
52
+ return {
53
+ skinUrl,
54
+ skinSha1,
55
+ };
56
+ }
57
+
58
+ return null;
59
+ } catch (error) {
60
+ console.debug(`Failed to update skin render for account ${account.id}:`, error);
61
+ return null;
62
+ }
63
+ }
64
+