@ozdao/martyrs 0.2.485 → 0.2.486

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 (345) hide show
  1. package/dist/{Media-DlUBwVWs.js → Media-CXQSPHt2.js} +1 -1
  2. package/dist/{Media-ByPHBvAU.cjs → Media-DhpD64nT.cjs} +1 -1
  3. package/dist/_virtual/index.cjs +4 -4
  4. package/dist/_virtual/index.js +4 -4
  5. package/dist/_virtual/index2.cjs +4 -4
  6. package/dist/_virtual/index2.js +4 -4
  7. package/dist/auth.server.cjs +2 -23
  8. package/dist/auth.server.js +1 -22
  9. package/dist/globals.crud-BQG1Lm0A.js +90 -0
  10. package/dist/globals.crud-Dv7UXbRM.cjs +89 -0
  11. package/dist/globals.server.cjs +3 -322
  12. package/dist/globals.server.js +1 -303
  13. package/dist/globals.websocket-DzvdIBf6.js +306 -0
  14. package/dist/globals.websocket-k6_B1T7k.cjs +322 -0
  15. package/dist/{main-CK6rC5Sz.js → main-Cfh5138F.js} +2155 -2087
  16. package/dist/main-DKJqboZy.cjs +11 -0
  17. package/dist/martyrs/src/components/Button/{Button.vue2.cjs → Button.vue.cjs} +2 -2
  18. package/dist/martyrs/src/components/Button/{Button.vue2.js.map → Button.vue.cjs.map} +1 -1
  19. package/dist/martyrs/src/components/Button/{Button.vue2.js → Button.vue.js} +2 -2
  20. package/dist/martyrs/src/components/Button/Button.vue.js.map +1 -0
  21. package/dist/martyrs/src/components/{DatePicker → Calendar}/Calendar.vue.cjs +1 -1
  22. package/dist/martyrs/src/components/Calendar/Calendar.vue.cjs.map +1 -0
  23. package/dist/martyrs/src/components/{DatePicker → Calendar}/Calendar.vue.js +1 -1
  24. package/dist/martyrs/src/components/Calendar/Calendar.vue.js.map +1 -0
  25. package/dist/martyrs/src/components/Feed/Feed.vue.cjs +1 -1
  26. package/dist/martyrs/src/components/Feed/Feed.vue.cjs.map +1 -1
  27. package/dist/martyrs/src/components/Feed/Feed.vue.js +1 -1
  28. package/dist/martyrs/src/components/Feed/Feed.vue.js.map +1 -1
  29. package/dist/martyrs/src/components/FieldTags/FieldTags.vue.cjs +1 -1
  30. package/dist/martyrs/src/components/FieldTags/FieldTags.vue.js +1 -1
  31. package/dist/martyrs/src/components/Menu/{Menu.vue2.cjs → Menu.vue.cjs} +2 -2
  32. package/dist/martyrs/src/components/Menu/Menu.vue.cjs.map +1 -0
  33. package/dist/martyrs/src/components/Menu/{Menu.vue2.js → Menu.vue.js} +2 -2
  34. package/dist/martyrs/src/components/Menu/Menu.vue.js.map +1 -0
  35. package/dist/martyrs/src/components/Popup/{Popup.vue2.cjs → Popup.vue.cjs} +2 -2
  36. package/dist/martyrs/src/components/Popup/{Popup.vue2.js.map → Popup.vue.cjs.map} +1 -1
  37. package/dist/martyrs/src/components/Popup/{Popup.vue2.js → Popup.vue.js} +2 -2
  38. package/dist/martyrs/src/components/Popup/Popup.vue.js.map +1 -0
  39. package/dist/martyrs/src/modules/auth/views/components/pages/EnterPassword.vue.cjs +1 -1
  40. package/dist/martyrs/src/modules/auth/views/components/pages/EnterPassword.vue.js +1 -1
  41. package/dist/martyrs/src/modules/auth/views/components/pages/Invite.vue.cjs +1 -1
  42. package/dist/martyrs/src/modules/auth/views/components/pages/Invite.vue.js +1 -1
  43. package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.cjs +2 -2
  44. package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.js +2 -2
  45. package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEdit.vue.cjs +1 -1
  46. package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEdit.vue.js +1 -1
  47. package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEditAccount.vue.cjs +1 -1
  48. package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEditAccount.vue.js +1 -1
  49. package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEditProfile.vue.cjs +1 -1
  50. package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEditProfile.vue.js +1 -1
  51. package/dist/martyrs/src/modules/auth/views/components/pages/ResetPassword.vue.cjs +1 -1
  52. package/dist/martyrs/src/modules/auth/views/components/pages/ResetPassword.vue.js +1 -1
  53. package/dist/martyrs/src/modules/auth/views/components/pages/SignIn.vue.cjs +1 -1
  54. package/dist/martyrs/src/modules/auth/views/components/pages/SignIn.vue.js +1 -1
  55. package/dist/martyrs/src/modules/auth/views/components/pages/SignUp.vue.cjs +1 -1
  56. package/dist/martyrs/src/modules/auth/views/components/pages/SignUp.vue.js +1 -1
  57. package/dist/martyrs/src/modules/auth/views/components/sections/ProfileEditCredentials.vue.cjs +1 -1
  58. package/dist/martyrs/src/modules/auth/views/components/sections/ProfileEditCredentials.vue.js +1 -1
  59. package/dist/martyrs/src/modules/community/components/pages/BlogPost.vue.cjs +2 -2
  60. package/dist/martyrs/src/modules/community/components/pages/BlogPost.vue.js +2 -2
  61. package/dist/martyrs/src/modules/community/components/pages/CreateBlogPost.vue.cjs +3 -3
  62. package/dist/martyrs/src/modules/community/components/pages/CreateBlogPost.vue.js +3 -3
  63. package/dist/martyrs/src/modules/events/components/elements/ButtonCheck.vue.cjs +1 -1
  64. package/dist/martyrs/src/modules/events/components/elements/ButtonCheck.vue.js +1 -1
  65. package/dist/martyrs/src/modules/events/components/elements/ButtonJoin.vue.cjs +1 -1
  66. package/dist/martyrs/src/modules/events/components/elements/ButtonJoin.vue.js +1 -1
  67. package/dist/martyrs/src/modules/events/components/pages/EditEvent.vue.cjs +2 -2
  68. package/dist/martyrs/src/modules/events/components/pages/EditEvent.vue.cjs.map +1 -1
  69. package/dist/martyrs/src/modules/events/components/pages/EditEvent.vue.js +2 -2
  70. package/dist/martyrs/src/modules/events/components/pages/EditEvent.vue.js.map +1 -1
  71. package/dist/martyrs/src/modules/events/components/pages/EditEventTickets.vue.cjs +2 -2
  72. package/dist/martyrs/src/modules/events/components/pages/EditEventTickets.vue.js +2 -2
  73. package/dist/martyrs/src/modules/events/components/pages/Events.vue.cjs +1 -1
  74. package/dist/martyrs/src/modules/events/components/pages/Events.vue.js +1 -1
  75. package/dist/martyrs/src/modules/gallery/components/pages/Gallery.vue.cjs +1 -1
  76. package/dist/martyrs/src/modules/gallery/components/pages/Gallery.vue.js +1 -1
  77. package/dist/martyrs/src/modules/gallery/components/sections/BackofficeGallery.vue.cjs +2 -2
  78. package/dist/martyrs/src/modules/gallery/components/sections/BackofficeGallery.vue.js +2 -2
  79. package/dist/martyrs/src/modules/globals/views/classes/globals.i18n.cjs +1 -1
  80. package/dist/martyrs/src/modules/globals/views/classes/globals.i18n.js +1 -1
  81. package/dist/martyrs/src/modules/globals/views/components/blocks/AlertDialog.vue.cjs +1 -1
  82. package/dist/martyrs/src/modules/globals/views/components/blocks/AlertDialog.vue.js +1 -1
  83. package/dist/martyrs/src/modules/globals/views/components/blocks/CardHeader.vue.cjs +1 -1
  84. package/dist/martyrs/src/modules/globals/views/components/blocks/CardHeader.vue.js +1 -1
  85. package/dist/martyrs/src/modules/globals/views/components/blocks/PopupAuth.vue.cjs +2 -2
  86. package/dist/martyrs/src/modules/globals/views/components/blocks/PopupAuth.vue.js +2 -2
  87. package/dist/martyrs/src/modules/globals/views/components/blocks/PopupDateSelector.vue.cjs +3 -3
  88. package/dist/martyrs/src/modules/globals/views/components/blocks/PopupDateSelector.vue.cjs.map +1 -1
  89. package/dist/martyrs/src/modules/globals/views/components/blocks/PopupDateSelector.vue.js +3 -3
  90. package/dist/martyrs/src/modules/globals/views/components/blocks/PopupDateSelector.vue.js.map +1 -1
  91. package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.cjs +2 -2
  92. package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.js +2 -2
  93. package/dist/martyrs/src/modules/globals/views/components/partials/Header.vue.cjs +1 -1
  94. package/dist/martyrs/src/modules/globals/views/components/partials/Header.vue.js +1 -1
  95. package/dist/martyrs/src/modules/globals/views/components/partials/NavigationBar.vue.cjs +1 -1
  96. package/dist/martyrs/src/modules/globals/views/components/partials/NavigationBar.vue.js +1 -1
  97. package/dist/martyrs/src/modules/globals/views/components/sections/Filters.vue2.cjs +1 -1
  98. package/dist/martyrs/src/modules/globals/views/components/sections/Filters.vue2.js +1 -1
  99. package/dist/martyrs/src/modules/globals/views/utils/axios-instance.cjs.map +1 -1
  100. package/dist/martyrs/src/modules/globals/views/utils/axios-instance.js.map +1 -1
  101. package/dist/martyrs/src/modules/music/components/cards/AlbumCard.vue.cjs +87 -0
  102. package/dist/martyrs/src/modules/music/components/cards/AlbumCard.vue.cjs.map +1 -0
  103. package/dist/martyrs/src/modules/music/components/cards/AlbumCard.vue.js +87 -0
  104. package/dist/martyrs/src/modules/music/components/cards/AlbumCard.vue.js.map +1 -0
  105. package/dist/martyrs/src/modules/music/components/cards/ArtistCard.vue.cjs +83 -0
  106. package/dist/martyrs/src/modules/music/components/cards/ArtistCard.vue.cjs.map +1 -0
  107. package/dist/martyrs/src/modules/music/components/cards/ArtistCard.vue.js +83 -0
  108. package/dist/martyrs/src/modules/music/components/cards/ArtistCard.vue.js.map +1 -0
  109. package/dist/martyrs/src/modules/music/components/cards/PlaylistCard.vue.cjs +83 -0
  110. package/dist/martyrs/src/modules/music/components/cards/PlaylistCard.vue.cjs.map +1 -0
  111. package/dist/martyrs/src/modules/music/components/cards/PlaylistCard.vue.js +83 -0
  112. package/dist/martyrs/src/modules/music/components/cards/PlaylistCard.vue.js.map +1 -0
  113. package/dist/martyrs/src/modules/music/components/cards/TrackCard.vue.cjs +68 -0
  114. package/dist/martyrs/src/modules/music/components/cards/TrackCard.vue.cjs.map +1 -0
  115. package/dist/martyrs/src/modules/music/components/cards/TrackCard.vue.js +68 -0
  116. package/dist/martyrs/src/modules/music/components/cards/TrackCard.vue.js.map +1 -0
  117. package/dist/martyrs/src/modules/music/components/forms/PlaylistForm.vue.cjs +174 -0
  118. package/dist/martyrs/src/modules/music/components/forms/PlaylistForm.vue.cjs.map +1 -0
  119. package/dist/martyrs/src/modules/music/components/forms/PlaylistForm.vue.js +174 -0
  120. package/dist/martyrs/src/modules/music/components/forms/PlaylistForm.vue.js.map +1 -0
  121. package/dist/martyrs/src/modules/music/components/forms/SearchForm.vue.cjs +80 -0
  122. package/dist/martyrs/src/modules/music/components/forms/SearchForm.vue.cjs.map +1 -0
  123. package/dist/martyrs/src/modules/music/components/forms/SearchForm.vue.js +80 -0
  124. package/dist/martyrs/src/modules/music/components/forms/SearchForm.vue.js.map +1 -0
  125. package/dist/martyrs/src/modules/music/components/forms/UploadForm.vue.cjs +328 -0
  126. package/dist/martyrs/src/modules/music/components/forms/UploadForm.vue.cjs.map +1 -0
  127. package/dist/martyrs/src/modules/music/components/forms/UploadForm.vue.js +328 -0
  128. package/dist/martyrs/src/modules/music/components/forms/UploadForm.vue.js.map +1 -0
  129. package/dist/martyrs/src/modules/music/components/layouts/MusicLayout.vue.cjs +115 -0
  130. package/dist/martyrs/src/modules/music/components/layouts/MusicLayout.vue.cjs.map +1 -0
  131. package/dist/martyrs/src/modules/music/components/layouts/MusicLayout.vue.js +115 -0
  132. package/dist/martyrs/src/modules/music/components/layouts/MusicLayout.vue.js.map +1 -0
  133. package/dist/martyrs/src/modules/music/components/lists/AlbumList.vue.cjs +44 -0
  134. package/dist/martyrs/src/modules/music/components/lists/AlbumList.vue.cjs.map +1 -0
  135. package/dist/martyrs/src/modules/music/components/lists/AlbumList.vue.js +44 -0
  136. package/dist/martyrs/src/modules/music/components/lists/AlbumList.vue.js.map +1 -0
  137. package/dist/martyrs/src/modules/music/components/lists/ArtistList.vue.cjs +305 -0
  138. package/dist/martyrs/src/modules/music/components/lists/ArtistList.vue.cjs.map +1 -0
  139. package/dist/martyrs/src/modules/music/components/lists/ArtistList.vue.js +305 -0
  140. package/dist/martyrs/src/modules/music/components/lists/ArtistList.vue.js.map +1 -0
  141. package/dist/martyrs/src/modules/music/components/lists/PlaylistList.vue.cjs +44 -0
  142. package/dist/martyrs/src/modules/music/components/lists/PlaylistList.vue.cjs.map +1 -0
  143. package/dist/martyrs/src/modules/music/components/lists/PlaylistList.vue.js +44 -0
  144. package/dist/martyrs/src/modules/music/components/lists/PlaylistList.vue.js.map +1 -0
  145. package/dist/martyrs/src/modules/music/components/lists/TrackList.vue.cjs +199 -0
  146. package/dist/martyrs/src/modules/music/components/lists/TrackList.vue.cjs.map +1 -0
  147. package/dist/martyrs/src/modules/music/components/lists/TrackList.vue.js +199 -0
  148. package/dist/martyrs/src/modules/music/components/lists/TrackList.vue.js.map +1 -0
  149. package/dist/martyrs/src/modules/music/components/pages/AlbumDetail.vue.cjs +290 -0
  150. package/dist/martyrs/src/modules/music/components/pages/AlbumDetail.vue.cjs.map +1 -0
  151. package/dist/martyrs/src/modules/music/components/pages/AlbumDetail.vue.js +290 -0
  152. package/dist/martyrs/src/modules/music/components/pages/AlbumDetail.vue.js.map +1 -0
  153. package/dist/martyrs/src/modules/music/components/pages/ArtistDetail.vue.cjs +467 -0
  154. package/dist/martyrs/src/modules/music/components/pages/ArtistDetail.vue.cjs.map +1 -0
  155. package/dist/martyrs/src/modules/music/components/pages/ArtistDetail.vue.js +467 -0
  156. package/dist/martyrs/src/modules/music/components/pages/ArtistDetail.vue.js.map +1 -0
  157. package/dist/martyrs/src/modules/music/components/pages/ArtistForm.vue.cjs +382 -0
  158. package/dist/martyrs/src/modules/music/components/pages/ArtistForm.vue.cjs.map +1 -0
  159. package/dist/martyrs/src/modules/music/components/pages/ArtistForm.vue.js +382 -0
  160. package/dist/martyrs/src/modules/music/components/pages/ArtistForm.vue.js.map +1 -0
  161. package/dist/martyrs/src/modules/music/components/pages/ArtistManager.vue.cjs +303 -0
  162. package/dist/martyrs/src/modules/music/components/pages/ArtistManager.vue.cjs.map +1 -0
  163. package/dist/martyrs/src/modules/music/components/pages/ArtistManager.vue.js +303 -0
  164. package/dist/martyrs/src/modules/music/components/pages/ArtistManager.vue.js.map +1 -0
  165. package/dist/martyrs/src/modules/music/components/pages/MusicHome.vue.cjs +221 -0
  166. package/dist/martyrs/src/modules/music/components/pages/MusicHome.vue.cjs.map +1 -0
  167. package/dist/martyrs/src/modules/music/components/pages/MusicHome.vue.js +221 -0
  168. package/dist/martyrs/src/modules/music/components/pages/MusicHome.vue.js.map +1 -0
  169. package/dist/martyrs/src/modules/music/components/pages/MusicLibrary.vue.cjs +200 -0
  170. package/dist/martyrs/src/modules/music/components/pages/MusicLibrary.vue.cjs.map +1 -0
  171. package/dist/martyrs/src/modules/music/components/pages/MusicLibrary.vue.js +200 -0
  172. package/dist/martyrs/src/modules/music/components/pages/MusicLibrary.vue.js.map +1 -0
  173. package/dist/martyrs/src/modules/music/components/pages/MusicUpload.vue.cjs +50 -0
  174. package/dist/martyrs/src/modules/music/components/pages/MusicUpload.vue.cjs.map +1 -0
  175. package/dist/martyrs/src/modules/music/components/pages/MusicUpload.vue.js +50 -0
  176. package/dist/martyrs/src/modules/music/components/pages/MusicUpload.vue.js.map +1 -0
  177. package/dist/martyrs/src/modules/music/components/pages/PlaylistDetail.vue.cjs +556 -0
  178. package/dist/martyrs/src/modules/music/components/pages/PlaylistDetail.vue.cjs.map +1 -0
  179. package/dist/martyrs/src/modules/music/components/pages/PlaylistDetail.vue.js +556 -0
  180. package/dist/martyrs/src/modules/music/components/pages/PlaylistDetail.vue.js.map +1 -0
  181. package/dist/martyrs/src/modules/music/components/pages/SearchResults.vue.cjs +449 -0
  182. package/dist/martyrs/src/modules/music/components/pages/SearchResults.vue.cjs.map +1 -0
  183. package/dist/martyrs/src/modules/music/components/pages/SearchResults.vue.js +449 -0
  184. package/dist/martyrs/src/modules/music/components/pages/SearchResults.vue.js.map +1 -0
  185. package/dist/martyrs/src/modules/music/components/pages/TrackDetail.vue.cjs +87 -0
  186. package/dist/martyrs/src/modules/music/components/pages/TrackDetail.vue.cjs.map +1 -0
  187. package/dist/martyrs/src/modules/music/components/pages/TrackDetail.vue.js +87 -0
  188. package/dist/martyrs/src/modules/music/components/pages/TrackDetail.vue.js.map +1 -0
  189. package/dist/martyrs/src/modules/music/components/player/MusicPlayer.vue.cjs +227 -0
  190. package/dist/martyrs/src/modules/music/components/player/MusicPlayer.vue.cjs.map +1 -0
  191. package/dist/martyrs/src/modules/music/components/player/MusicPlayer.vue.js +227 -0
  192. package/dist/martyrs/src/modules/music/components/player/MusicPlayer.vue.js.map +1 -0
  193. package/dist/martyrs/src/modules/music/components/player/TrackProgress.vue.cjs +85 -0
  194. package/dist/martyrs/src/modules/music/components/player/TrackProgress.vue.cjs.map +1 -0
  195. package/dist/martyrs/src/modules/music/components/player/TrackProgress.vue.js +85 -0
  196. package/dist/martyrs/src/modules/music/components/player/TrackProgress.vue.js.map +1 -0
  197. package/dist/martyrs/src/modules/music/components/player/VolumeControl.vue.cjs +71 -0
  198. package/dist/martyrs/src/modules/music/components/player/VolumeControl.vue.cjs.map +1 -0
  199. package/dist/martyrs/src/modules/music/components/player/VolumeControl.vue.js +71 -0
  200. package/dist/martyrs/src/modules/music/components/player/VolumeControl.vue.js.map +1 -0
  201. package/dist/martyrs/src/modules/music/music.client.cjs +137 -0
  202. package/dist/martyrs/src/modules/music/music.client.cjs.map +1 -0
  203. package/dist/martyrs/src/modules/music/music.client.js +137 -0
  204. package/dist/martyrs/src/modules/music/music.client.js.map +1 -0
  205. package/dist/martyrs/src/modules/music/router/music.cjs +99 -0
  206. package/dist/martyrs/src/modules/music/router/music.cjs.map +1 -0
  207. package/dist/martyrs/src/modules/music/router/music.js +99 -0
  208. package/dist/martyrs/src/modules/music/router/music.js.map +1 -0
  209. package/dist/martyrs/src/modules/music/store/albums.cjs +167 -0
  210. package/dist/martyrs/src/modules/music/store/albums.cjs.map +1 -0
  211. package/dist/martyrs/src/modules/music/store/albums.js +167 -0
  212. package/dist/martyrs/src/modules/music/store/albums.js.map +1 -0
  213. package/dist/martyrs/src/modules/music/store/artists.cjs +154 -0
  214. package/dist/martyrs/src/modules/music/store/artists.cjs.map +1 -0
  215. package/dist/martyrs/src/modules/music/store/artists.js +154 -0
  216. package/dist/martyrs/src/modules/music/store/artists.js.map +1 -0
  217. package/dist/martyrs/src/modules/music/store/player.cjs +297 -0
  218. package/dist/martyrs/src/modules/music/store/player.cjs.map +1 -0
  219. package/dist/martyrs/src/modules/music/store/player.js +297 -0
  220. package/dist/martyrs/src/modules/music/store/player.js.map +1 -0
  221. package/dist/martyrs/src/modules/music/store/playlists.cjs +174 -0
  222. package/dist/martyrs/src/modules/music/store/playlists.cjs.map +1 -0
  223. package/dist/martyrs/src/modules/music/store/playlists.js +174 -0
  224. package/dist/martyrs/src/modules/music/store/playlists.js.map +1 -0
  225. package/dist/martyrs/src/modules/music/store/search.cjs +109 -0
  226. package/dist/martyrs/src/modules/music/store/search.cjs.map +1 -0
  227. package/dist/martyrs/src/modules/music/store/search.js +109 -0
  228. package/dist/martyrs/src/modules/music/store/search.js.map +1 -0
  229. package/dist/martyrs/src/modules/music/store/tracks.cjs +180 -0
  230. package/dist/martyrs/src/modules/music/store/tracks.cjs.map +1 -0
  231. package/dist/martyrs/src/modules/music/store/tracks.js +180 -0
  232. package/dist/martyrs/src/modules/music/store/tracks.js.map +1 -0
  233. package/dist/martyrs/src/modules/notifications/components/elements/NotificationBadge.vue.cjs +1 -1
  234. package/dist/martyrs/src/modules/notifications/components/elements/NotificationBadge.vue.js +1 -1
  235. package/dist/martyrs/src/modules/orders/components/pages/OrderBackoffice.vue.cjs +2 -2
  236. package/dist/martyrs/src/modules/orders/components/pages/OrderBackoffice.vue.js +2 -2
  237. package/dist/martyrs/src/modules/orders/components/pages/OrderCreate.vue.cjs +1 -1
  238. package/dist/martyrs/src/modules/orders/components/pages/OrderCreate.vue.js +1 -1
  239. package/dist/martyrs/src/modules/orders/components/pages/OrderCreateBackoffice.vue.cjs +2 -2
  240. package/dist/martyrs/src/modules/orders/components/pages/OrderCreateBackoffice.vue.js +2 -2
  241. package/dist/martyrs/src/modules/orders/components/sections/FormAddCustomer.vue.cjs +1 -1
  242. package/dist/martyrs/src/modules/orders/components/sections/FormAddCustomer.vue.js +1 -1
  243. package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.cjs +1 -1
  244. package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.js +1 -1
  245. package/dist/martyrs/src/modules/organizations/components/elements/ButtonToggleMembership.vue.cjs +1 -1
  246. package/dist/martyrs/src/modules/organizations/components/elements/ButtonToggleMembership.vue.js +1 -1
  247. package/dist/martyrs/src/modules/organizations/components/pages/DepartmentEdit.vue.cjs +2 -2
  248. package/dist/martyrs/src/modules/organizations/components/pages/DepartmentEdit.vue.js +2 -2
  249. package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.cjs +2 -2
  250. package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.js +2 -2
  251. package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.cjs +1 -1
  252. package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.js +1 -1
  253. package/dist/martyrs/src/modules/organizations/components/pages/OrganizationBackoffice.vue.cjs +1 -1
  254. package/dist/martyrs/src/modules/organizations/components/pages/OrganizationBackoffice.vue.js +1 -1
  255. package/dist/martyrs/src/modules/organizations/components/pages/OrganizationEdit.vue.cjs +2 -2
  256. package/dist/martyrs/src/modules/organizations/components/pages/OrganizationEdit.vue.js +2 -2
  257. package/dist/martyrs/src/modules/organizations/components/sections/Documents.vue.cjs +2 -2
  258. package/dist/martyrs/src/modules/organizations/components/sections/Documents.vue.js +2 -2
  259. package/dist/martyrs/src/modules/organizations/components/sections/MembersAdd.vue.cjs +1 -1
  260. package/dist/martyrs/src/modules/organizations/components/sections/MembersAdd.vue.js +1 -1
  261. package/dist/martyrs/src/modules/organizations/components/sections/Organizations.vue.cjs +1 -1
  262. package/dist/martyrs/src/modules/organizations/components/sections/Organizations.vue.js +1 -1
  263. package/dist/martyrs/src/modules/organizations/router/organizations.cjs +1 -1
  264. package/dist/martyrs/src/modules/organizations/router/organizations.js +1 -1
  265. package/dist/martyrs/src/modules/pages/views/components/blocks/CardPage.vue.cjs +1 -1
  266. package/dist/martyrs/src/modules/pages/views/components/blocks/CardPage.vue.js +1 -1
  267. package/dist/martyrs/src/modules/pages/views/components/pages/PageEdit.vue.cjs +1 -1
  268. package/dist/martyrs/src/modules/pages/views/components/pages/PageEdit.vue.js +1 -1
  269. package/dist/martyrs/src/modules/pages/views/components/partials/SidebarPages.vue.cjs +2 -2
  270. package/dist/martyrs/src/modules/pages/views/components/partials/SidebarPages.vue.js +2 -2
  271. package/dist/martyrs/src/modules/products/components/blocks/ProductImages.vue.cjs +1 -1
  272. package/dist/martyrs/src/modules/products/components/blocks/ProductImages.vue.js +1 -1
  273. package/dist/martyrs/src/modules/products/components/pages/Categories.vue.cjs +1 -1
  274. package/dist/martyrs/src/modules/products/components/pages/Categories.vue.js +1 -1
  275. package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.cjs +2 -2
  276. package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.js +2 -2
  277. package/dist/martyrs/src/modules/products/components/pages/LeftoverEdit.vue.cjs +2 -2
  278. package/dist/martyrs/src/modules/products/components/pages/LeftoverEdit.vue.js +2 -2
  279. package/dist/martyrs/src/modules/products/components/pages/Leftovers.vue.cjs +2 -2
  280. package/dist/martyrs/src/modules/products/components/pages/Leftovers.vue.js +1 -1
  281. package/dist/martyrs/src/modules/products/components/pages/Product.vue.cjs +2 -2
  282. package/dist/martyrs/src/modules/products/components/pages/Product.vue.cjs.map +1 -1
  283. package/dist/martyrs/src/modules/products/components/pages/Product.vue.js +2 -2
  284. package/dist/martyrs/src/modules/products/components/pages/Product.vue.js.map +1 -1
  285. package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.cjs +1 -1
  286. package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.js +1 -1
  287. package/dist/martyrs/src/modules/products/components/sections/EditAttributes.vue.cjs +2 -2
  288. package/dist/martyrs/src/modules/products/components/sections/EditAttributes.vue.js +2 -2
  289. package/dist/martyrs/src/modules/products/components/sections/EditDiscounts.vue.cjs +2 -2
  290. package/dist/martyrs/src/modules/products/components/sections/EditDiscounts.vue.js +2 -2
  291. package/dist/martyrs/src/modules/products/components/sections/EditIngredients.vue.cjs +1 -1
  292. package/dist/martyrs/src/modules/products/components/sections/EditIngredients.vue.js +1 -1
  293. package/dist/martyrs/src/modules/products/components/sections/EditRecommended.vue.cjs +1 -1
  294. package/dist/martyrs/src/modules/products/components/sections/EditRecommended.vue.js +1 -1
  295. package/dist/martyrs/src/modules/products/components/sections/EditVariants.vue.cjs +2 -2
  296. package/dist/martyrs/src/modules/products/components/sections/EditVariants.vue.js +2 -2
  297. package/dist/martyrs/src/modules/products/components/sections/ProductConfigurator.vue.cjs +1 -1
  298. package/dist/martyrs/src/modules/products/components/sections/ProductConfigurator.vue.js +1 -1
  299. package/dist/martyrs/src/modules/products/components/sections/ProductsRecommended.vue.cjs +1 -1
  300. package/dist/martyrs/src/modules/products/components/sections/ProductsRecommended.vue.js +1 -1
  301. package/dist/martyrs/src/modules/products/components/sections/SectionProduct.vue.cjs +1 -1
  302. package/dist/martyrs/src/modules/products/components/sections/SectionProduct.vue.js +1 -1
  303. package/dist/martyrs/src/modules/rents/views/components/pages/RentsEdit.vue.cjs +1 -1
  304. package/dist/martyrs/src/modules/rents/views/components/pages/RentsEdit.vue.js +1 -1
  305. package/dist/martyrs/src/modules/reports/components/sections/FormReport.vue.cjs +2 -2
  306. package/dist/martyrs/src/modules/reports/components/sections/FormReport.vue.js +2 -2
  307. package/dist/martyrs/src/modules/spots/components/pages/Map.vue.cjs +1 -1
  308. package/dist/martyrs/src/modules/spots/components/pages/Map.vue.js +1 -1
  309. package/dist/martyrs/src/modules/spots/components/pages/SpotEdit.vue.cjs +2 -2
  310. package/dist/martyrs/src/modules/spots/components/pages/SpotEdit.vue.js +2 -2
  311. package/dist/martyrs/src/modules/spots/components/sections/WorktimeEdit.vue.cjs +2 -2
  312. package/dist/martyrs/src/modules/spots/components/sections/WorktimeEdit.vue.js +2 -2
  313. package/dist/martyrs/src/modules/wallet/views/components/pages/Wallet.vue.cjs +2 -2
  314. package/dist/martyrs/src/modules/wallet/views/components/pages/Wallet.vue.js +2 -2
  315. package/dist/martyrs.cjs.js +1 -1
  316. package/dist/martyrs.css +1 -1
  317. package/dist/martyrs.es.js +38 -36
  318. package/dist/music.server.cjs +1407 -0
  319. package/dist/music.server.js +1407 -0
  320. package/dist/node_modules/.pnpm/qrcode@1.5.4/node_modules/qrcode/lib/core/utils.cjs +1 -1
  321. package/dist/node_modules/.pnpm/qrcode@1.5.4/node_modules/qrcode/lib/core/utils.js +1 -1
  322. package/dist/node_modules/.pnpm/qrcode@1.5.4/node_modules/qrcode/lib/renderer/utils.cjs +1 -1
  323. package/dist/node_modules/.pnpm/qrcode@1.5.4/node_modules/qrcode/lib/renderer/utils.js +1 -1
  324. package/dist/orders.server.cjs +3 -88
  325. package/dist/orders.server.js +2 -87
  326. package/dist/socials.schema-BOZV82Mp.js +25 -0
  327. package/dist/socials.schema-CtpSF9dE.cjs +24 -0
  328. package/dist/style.css +155 -15
  329. package/package.json +1 -1
  330. package/src/.martyrs/filemap.json +2 -2
  331. package/src/components/Feed/Feed.vue +1 -1
  332. package/src/components/index.js +2 -0
  333. package/src/main.js +6 -0
  334. package/src/modules/events/components/pages/EditEvent.vue +1 -1
  335. package/src/modules/globals/views/components/blocks/PopupDateSelector.vue +1 -1
  336. package/src/modules/globals/views/utils/axios-instance.js +15 -1
  337. package/src/modules/products/components/pages/Product.vue +1 -1
  338. package/dist/main-137vO86w.cjs +0 -11
  339. package/dist/martyrs/src/components/Button/Button.vue2.cjs.map +0 -1
  340. package/dist/martyrs/src/components/DatePicker/Calendar.vue.cjs.map +0 -1
  341. package/dist/martyrs/src/components/DatePicker/Calendar.vue.js.map +0 -1
  342. package/dist/martyrs/src/components/Menu/Menu.vue2.cjs.map +0 -1
  343. package/dist/martyrs/src/components/Menu/Menu.vue2.js.map +0 -1
  344. package/dist/martyrs/src/components/Popup/Popup.vue2.cjs.map +0 -1
  345. /package/src/components/{DatePicker → Calendar}/Calendar.vue +0 -0
@@ -0,0 +1,1407 @@
1
+ "use strict";
2
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
+ const globals_abac = require("./globals.abac-Cm9e8Jdk.cjs");
4
+ const globals_logger = require("./globals.logger-CZMgIMlM.cjs");
5
+ const globals_websocket = require("./globals.websocket-k6_B1T7k.cjs");
6
+ const globals_crud = require("./globals.crud-Dv7UXbRM.cjs");
7
+ const fs$1 = require("fs");
8
+ const path$1 = require("path");
9
+ const common_schema = require("./common.schema-BzFEVNn3.cjs");
10
+ const engagement_schema = require("./engagement.schema-JADHu8pj.cjs");
11
+ const metadata_schema = require("./metadata.schema-RlxNv46L.cjs");
12
+ const ownership_schema = require("./ownership.schema-DCosqOc1.cjs");
13
+ const socials_schema = require("./socials.schema-CtpSF9dE.cjs");
14
+ const index = require("./index-YNOkL1mu.cjs");
15
+ const { getInstance: getInstance$1 } = globals_abac.globalsabac;
16
+ const MusicController = function(app, db) {
17
+ const logger = new globals_logger.Logger(db);
18
+ const cache = new globals_logger.Cache();
19
+ const abac = getInstance$1(db);
20
+ class MusicController2 extends globals_crud.CRUD {
21
+ constructor(basePath, app2, db2, model, options) {
22
+ super(basePath, app2, db2, model, options);
23
+ this.logger = logger;
24
+ this.cache = cache;
25
+ this.abac = abac;
26
+ }
27
+ // Override the create method to handle ownership
28
+ async create(req, res) {
29
+ try {
30
+ console.log(`[MusicController] Create request received:`, {
31
+ userId: req.userId,
32
+ body: req.body
33
+ });
34
+ if (!req.userId) {
35
+ console.error("[MusicController] No userId found in request, auth middleware may have failed");
36
+ return res.status(401).json({
37
+ errorCode: "AUTHENTICATION_REQUIRED",
38
+ message: "You must be authenticated to perform this action"
39
+ });
40
+ }
41
+ if (!req.body.creator) {
42
+ req.body.creator = {
43
+ type: "user",
44
+ // Note lowercase - must match your schema expectations
45
+ target: req.userId
46
+ };
47
+ }
48
+ if (!req.body.owner) {
49
+ req.body.owner = {
50
+ type: "user",
51
+ // Note lowercase - must match your schema expectations
52
+ target: req.userId
53
+ };
54
+ }
55
+ console.log(`[MusicController] Checking access with ABAC`);
56
+ const accessResult = await this.abac.checkAccess({
57
+ user: req.userId,
58
+ resource: this.model.collection.collectionName,
59
+ action: "create",
60
+ data: req.body
61
+ });
62
+ console.log(`[MusicController] Access check result:`, accessResult);
63
+ if (!accessResult.allowed) {
64
+ console.error(`[MusicController] Access denied:`, accessResult.reason);
65
+ return res.status(403).json({
66
+ errorCode: accessResult.reason,
67
+ message: "Access Denied"
68
+ });
69
+ }
70
+ console.log(`[MusicController] Creating record with data:`, req.body);
71
+ const createdData = await this.model.create(req.body);
72
+ await this.cache.flush();
73
+ console.log(`[MusicController] Record created successfully:`, createdData._id);
74
+ res.status(201).json(createdData);
75
+ } catch (error) {
76
+ console.error(`[MusicController] Error creating record:`, error);
77
+ this.logger.error(`Error creating ${this.model.collection.collectionName}: ${error.message}`);
78
+ res.status(500).json({ error: error.message });
79
+ }
80
+ }
81
+ // Override the update method to check ownership
82
+ async update(req, res) {
83
+ try {
84
+ const resourceId = req.body._id;
85
+ const resource = await this.model.findById(resourceId);
86
+ if (!resource) {
87
+ return res.status(404).json({ error: "Resource not found" });
88
+ }
89
+ const accessResult = await this.abac.checkAccess({
90
+ user: req.userId,
91
+ resource: this.model.collection.collectionName,
92
+ action: "update",
93
+ data: req.body,
94
+ currentResource: resource
95
+ });
96
+ if (!accessResult.allowed) {
97
+ return res.status(403).json({
98
+ errorCode: accessResult.reason,
99
+ message: "Access Denied"
100
+ });
101
+ }
102
+ const updatedData = await this.model.findOneAndUpdate({ _id: resourceId }, req.body, {
103
+ new: true,
104
+ runValidators: true
105
+ });
106
+ await this.cache.flush();
107
+ res.json(updatedData);
108
+ } catch (error) {
109
+ this.logger.error(`Error updating ${this.model.collection.collectionName}: ${error.message}`);
110
+ res.status(500).json({ error: error.message });
111
+ }
112
+ }
113
+ // Override the delete method to check ownership
114
+ async delete(req, res) {
115
+ try {
116
+ const resourceId = req.body._id;
117
+ const resource = await this.model.findById(resourceId);
118
+ if (!resource) {
119
+ return res.status(404).json({ error: "Resource not found" });
120
+ }
121
+ const accessResult = await this.abac.checkAccess({
122
+ user: req.userId,
123
+ resource: this.model.collection.collectionName,
124
+ action: "delete",
125
+ data: req.body,
126
+ currentResource: resource
127
+ });
128
+ if (!accessResult.allowed) {
129
+ return res.status(403).json({
130
+ errorCode: accessResult.reason,
131
+ message: "Access Denied"
132
+ });
133
+ }
134
+ await this.model.findOneAndDelete({ _id: resourceId });
135
+ await this.cache.flush();
136
+ res.status(204).send();
137
+ } catch (error) {
138
+ this.logger.error(`Error deleting ${this.model.collection.collectionName}: ${error.message}`);
139
+ res.status(500).json({ error: error.message });
140
+ }
141
+ }
142
+ }
143
+ return {
144
+ MusicController: MusicController2
145
+ };
146
+ };
147
+ const AlbumController = function(app, db) {
148
+ const { MusicController: MusicController$1 } = MusicController(app, db);
149
+ class AlbumController2 extends MusicController$1 {
150
+ constructor(app2) {
151
+ super("/api/albums", app2, db, db.album);
152
+ }
153
+ // Get tracks for a specific album
154
+ async getAlbumTracks(req, res) {
155
+ try {
156
+ const albumId = req.params.albumId;
157
+ const album = await db.album.findById(albumId);
158
+ if (!album) {
159
+ return res.status(404).json({ error: "Album not found" });
160
+ }
161
+ const accessResult = await this.abac.checkAccess({
162
+ user: req.userId,
163
+ resource: "albums",
164
+ action: "read",
165
+ currentResource: album
166
+ });
167
+ if (!accessResult.allowed && !album.isPublic) {
168
+ return res.status(403).json({
169
+ errorCode: accessResult.reason,
170
+ message: "Access Denied"
171
+ });
172
+ }
173
+ const tracks = await db.track.find({ album: albumId, status: "published" }).sort({ releaseDate: -1 });
174
+ res.json(tracks);
175
+ } catch (error) {
176
+ this.logger.error(`Error getting album tracks: ${error.message}`);
177
+ res.status(500).json({ error: error.message });
178
+ }
179
+ }
180
+ // Get featured albums
181
+ async getFeaturedAlbums(req, res) {
182
+ try {
183
+ const cacheKey = "featured-albums";
184
+ let featuredAlbums = await this.cache.get(cacheKey);
185
+ if (!featuredAlbums) {
186
+ featuredAlbums = await db.album.aggregate([
187
+ { $match: { status: "featured", isPublic: true } },
188
+ {
189
+ $lookup: {
190
+ from: "tracks",
191
+ localField: "_id",
192
+ foreignField: "album",
193
+ as: "tracks"
194
+ }
195
+ },
196
+ {
197
+ $addFields: {
198
+ trackCount: { $size: "$tracks" }
199
+ }
200
+ },
201
+ { $project: { tracks: 0 } },
202
+ { $sort: { releaseDate: -1 } },
203
+ { $limit: 10 }
204
+ ]);
205
+ await this.cache.set(cacheKey, featuredAlbums, 3600);
206
+ }
207
+ res.json(featuredAlbums);
208
+ } catch (error) {
209
+ this.logger.error(`Error getting featured albums: ${error.message}`);
210
+ res.status(500).json({ error: error.message });
211
+ }
212
+ }
213
+ }
214
+ const albumController = new AlbumController2(app, db);
215
+ return {
216
+ create: albumController.create.bind(albumController),
217
+ read: albumController.read.bind(albumController),
218
+ update: albumController.update.bind(albumController),
219
+ delete: albumController.delete.bind(albumController),
220
+ getAlbumTracks: albumController.getAlbumTracks.bind(albumController),
221
+ getFeaturedAlbums: albumController.getFeaturedAlbums.bind(albumController)
222
+ };
223
+ };
224
+ const ArtistController = function(app, db) {
225
+ const { MusicController: MusicController$1 } = MusicController(app, db);
226
+ class ArtistController2 extends MusicController$1 {
227
+ constructor(app2) {
228
+ super("/api/artists", app2, db, db.artist);
229
+ }
230
+ // Get artist discography
231
+ async getDiscography(req, res) {
232
+ try {
233
+ const artistId = req.params.artistId;
234
+ const artist = await db.artist.findById(artistId);
235
+ if (!artist) {
236
+ return res.status(404).json({ error: "Artist not found" });
237
+ }
238
+ const albums = await db.album.find({
239
+ artist: artistId,
240
+ status: "published",
241
+ isPublic: true
242
+ }).sort({ releaseDate: -1 });
243
+ const singleTracks = await db.track.find({
244
+ artist: artistId,
245
+ album: { $exists: false },
246
+ status: "published",
247
+ isPublic: true
248
+ }).sort({ releaseDate: -1 });
249
+ res.json({
250
+ artist,
251
+ albums,
252
+ singles: singleTracks
253
+ });
254
+ } catch (error) {
255
+ this.logger.error(`Error getting artist discography: ${error.message}`);
256
+ res.status(500).json({ error: error.message });
257
+ }
258
+ }
259
+ // Verify an artist (admin only)
260
+ async verifyArtist(req, res) {
261
+ try {
262
+ const artistId = req.params.artistId;
263
+ if (!req.userRoles.includes("ROLE_ADMIN")) {
264
+ return res.status(403).json({ error: "Only administrators can verify artists" });
265
+ }
266
+ const artist = await db.artist.findById(artistId);
267
+ if (!artist) {
268
+ return res.status(404).json({ error: "Artist not found" });
269
+ }
270
+ artist.isVerified = true;
271
+ await artist.save();
272
+ await this.cache.flush();
273
+ res.json({ success: true, artist });
274
+ } catch (error) {
275
+ this.logger.error(`Error verifying artist: ${error.message}`);
276
+ res.status(500).json({ error: error.message });
277
+ }
278
+ }
279
+ // Get related artists
280
+ async getRelatedArtists(req, res) {
281
+ try {
282
+ const artistId = req.params.artistId;
283
+ const artist = await db.artist.findById(artistId);
284
+ if (!artist) {
285
+ return res.status(404).json({ error: "Artist not found" });
286
+ }
287
+ const relatedArtists = await db.artist.find({
288
+ _id: { $ne: artistId },
289
+ genre: { $in: artist.genre },
290
+ status: "published"
291
+ }).limit(5);
292
+ res.json(relatedArtists);
293
+ } catch (error) {
294
+ this.logger.error(`Error getting related artists: ${error.message}`);
295
+ res.status(500).json({ error: error.message });
296
+ }
297
+ }
298
+ }
299
+ const artistController = new ArtistController2(app, db);
300
+ return {
301
+ create: artistController.create.bind(artistController),
302
+ read: artistController.read.bind(artistController),
303
+ update: artistController.update.bind(artistController),
304
+ delete: artistController.delete.bind(artistController),
305
+ getDiscography: artistController.getDiscography.bind(artistController),
306
+ verifyArtist: artistController.verifyArtist.bind(artistController),
307
+ getRelatedArtists: artistController.getRelatedArtists.bind(artistController)
308
+ };
309
+ };
310
+ const GenreController = function(app, db) {
311
+ const { MusicController: MusicController$1 } = MusicController(app, db);
312
+ class GenreController2 extends MusicController$1 {
313
+ constructor(app2) {
314
+ super("/api/genres", app2, db, db.genre);
315
+ }
316
+ // Get tracks by genre
317
+ async getGenreTracks(req, res) {
318
+ try {
319
+ const genreId = req.params.genreId;
320
+ const genre = await db.genre.findById(genreId);
321
+ if (!genre) {
322
+ return res.status(404).json({ error: "Genre not found" });
323
+ }
324
+ const tracks = await db.track.find({
325
+ genre: genreId,
326
+ status: "published",
327
+ isPublic: true
328
+ }).sort({ releaseDate: -1 }).limit(50).populate("artist", "name").populate("album", "title coverUrl");
329
+ res.json({
330
+ genre,
331
+ tracks
332
+ });
333
+ } catch (error) {
334
+ this.logger.error(`Error getting genre tracks: ${error.message}`);
335
+ res.status(500).json({ error: error.message });
336
+ }
337
+ }
338
+ // Get popular genres
339
+ async getPopularGenres(req, res) {
340
+ try {
341
+ const limit = parseInt(req.query.limit) || 10;
342
+ const genres = await db.genre.find({
343
+ status: "published"
344
+ }).sort({ popularity: -1 }).limit(limit);
345
+ res.json(genres);
346
+ } catch (error) {
347
+ this.logger.error(`Error getting popular genres: ${error.message}`);
348
+ res.status(500).json({ error: error.message });
349
+ }
350
+ }
351
+ }
352
+ const genreController = new GenreController2(app, db);
353
+ return {
354
+ create: genreController.create.bind(genreController),
355
+ read: genreController.read.bind(genreController),
356
+ update: genreController.update.bind(genreController),
357
+ delete: genreController.delete.bind(genreController),
358
+ getGenreTracks: genreController.getGenreTracks.bind(genreController),
359
+ getPopularGenres: genreController.getPopularGenres.bind(genreController)
360
+ };
361
+ };
362
+ const PlaylistController = function(app, db) {
363
+ const { MusicController: MusicController$1 } = MusicController(app, db);
364
+ class PlaylistController2 extends MusicController$1 {
365
+ constructor(app2, db2) {
366
+ super("/api/playlists", app2, db2, db2.playlist);
367
+ }
368
+ // Add track to playlist
369
+ async addTrack(req, res) {
370
+ try {
371
+ const { playlistId, trackId } = req.params;
372
+ const playlist = await db.playlist.findById(playlistId);
373
+ if (!playlist) {
374
+ return res.status(404).json({ error: "Playlist not found" });
375
+ }
376
+ const accessResult = await this.abac.checkAccess({
377
+ user: req.userId,
378
+ resource: "playlists",
379
+ action: "update",
380
+ currentResource: playlist
381
+ });
382
+ if (!accessResult.allowed) {
383
+ return res.status(403).json({
384
+ errorCode: accessResult.reason,
385
+ message: "Access Denied"
386
+ });
387
+ }
388
+ const track = await db.track.findById(trackId);
389
+ if (!track) {
390
+ return res.status(404).json({ error: "Track not found" });
391
+ }
392
+ const trackExists = playlist.tracks.some((item) => item.track.toString() === trackId);
393
+ if (trackExists) {
394
+ return res.status(400).json({ error: "Track already in playlist" });
395
+ }
396
+ playlist.tracks.push({
397
+ track: trackId,
398
+ addedAt: /* @__PURE__ */ new Date()
399
+ });
400
+ await playlist.save();
401
+ await this.cache.flush();
402
+ res.json(playlist);
403
+ } catch (error) {
404
+ this.logger.error(`Error adding track to playlist: ${error.message}`);
405
+ res.status(500).json({ error: error.message });
406
+ }
407
+ }
408
+ // Remove track from playlist
409
+ async removeTrack(req, res) {
410
+ try {
411
+ const { playlistId, trackId } = req.params;
412
+ const playlist = await db.playlist.findById(playlistId);
413
+ if (!playlist) {
414
+ return res.status(404).json({ error: "Playlist not found" });
415
+ }
416
+ const accessResult = await this.abac.checkAccess({
417
+ user: req.userId,
418
+ resource: "playlists",
419
+ action: "update",
420
+ currentResource: playlist
421
+ });
422
+ if (!accessResult.allowed) {
423
+ return res.status(403).json({
424
+ errorCode: accessResult.reason,
425
+ message: "Access Denied"
426
+ });
427
+ }
428
+ playlist.tracks = playlist.tracks.filter((item) => item.track.toString() !== trackId);
429
+ await playlist.save();
430
+ await this.cache.flush();
431
+ res.json(playlist);
432
+ } catch (error) {
433
+ this.logger.error(`Error removing track from playlist: ${error.message}`);
434
+ res.status(500).json({ error: error.message });
435
+ }
436
+ }
437
+ // Get user playlists
438
+ async getUserPlaylists(req, res) {
439
+ try {
440
+ const userId = req.params.userId || req.userId;
441
+ const playlists = await db.playlist.find({
442
+ $or: [{ "owner.target": userId, "owner.type": "User" }, { collaborators: userId }]
443
+ }).sort({ updatedAt: -1 });
444
+ res.json(playlists);
445
+ } catch (error) {
446
+ this.logger.error(`Error getting user playlists: ${error.message}`);
447
+ res.status(500).json({ error: error.message });
448
+ }
449
+ }
450
+ // Add collaborator to playlist
451
+ async addCollaborator(req, res) {
452
+ try {
453
+ const { playlistId, userId } = req.params;
454
+ const playlist = await db.playlist.findById(playlistId);
455
+ if (!playlist) {
456
+ return res.status(404).json({ error: "Playlist not found" });
457
+ }
458
+ if (playlist.owner.target.toString() !== req.userId) {
459
+ return res.status(403).json({ error: "Only playlist owner can add collaborators" });
460
+ }
461
+ const user = await db.mongoose.model("User").findById(userId);
462
+ if (!user) {
463
+ return res.status(404).json({ error: "User not found" });
464
+ }
465
+ if (playlist.collaborators.includes(userId)) {
466
+ return res.status(400).json({ error: "User is already a collaborator" });
467
+ }
468
+ playlist.collaborators.push(userId);
469
+ playlist.isCollaborative = true;
470
+ await playlist.save();
471
+ await this.cache.flush();
472
+ res.json(playlist);
473
+ } catch (error) {
474
+ this.logger.error(`Error adding collaborator to playlist: ${error.message}`);
475
+ res.status(500).json({ error: error.message });
476
+ }
477
+ }
478
+ }
479
+ const playlistController = new PlaylistController2(app, db);
480
+ return {
481
+ create: playlistController.create.bind(playlistController),
482
+ read: playlistController.read.bind(playlistController),
483
+ update: playlistController.update.bind(playlistController),
484
+ delete: playlistController.delete.bind(playlistController),
485
+ addTrack: playlistController.addTrack.bind(playlistController),
486
+ removeTrack: playlistController.removeTrack.bind(playlistController),
487
+ getUserPlaylists: playlistController.getUserPlaylists.bind(playlistController),
488
+ addCollaborator: playlistController.addCollaborator.bind(playlistController)
489
+ };
490
+ };
491
+ const SearchController = function(app, db) {
492
+ const logger = new globals_logger.Logger(db);
493
+ const cache = new globals_logger.Cache();
494
+ async function search(req, res) {
495
+ try {
496
+ const { query, type, limit = 10 } = req.query;
497
+ if (!query || query.length < 2) {
498
+ return res.status(400).json({ error: "Search query must be at least 2 characters" });
499
+ }
500
+ const limitNum = parseInt(limit, 10);
501
+ const cacheKey = `search:${query}:${type || "all"}:${limitNum}`;
502
+ let results = await cache.get(cacheKey);
503
+ if (!results) {
504
+ results = {};
505
+ const searchRegex = new RegExp(query, "i");
506
+ const types = type ? [type] : ["tracks", "albums", "artists", "playlists", "genres"];
507
+ if (types.includes("tracks") || types.includes("all")) {
508
+ results.tracks = await db.track.find({
509
+ $or: [{ title: searchRegex }, { tags: searchRegex }],
510
+ status: "published",
511
+ isPublic: true
512
+ }).limit(limitNum);
513
+ }
514
+ if (types.includes("albums") || types.includes("all")) {
515
+ results.albums = await db.album.find({
516
+ $or: [{ title: searchRegex }, { description: searchRegex }, { tags: searchRegex }],
517
+ status: "published",
518
+ isPublic: true
519
+ }).limit(limitNum);
520
+ }
521
+ if (types.includes("artists") || types.includes("all")) {
522
+ results.artists = await db.artist.find({
523
+ $or: [{ name: searchRegex }, { bio: searchRegex }, { tags: searchRegex }],
524
+ status: "published"
525
+ }).limit(limitNum);
526
+ }
527
+ if (types.includes("playlists") || types.includes("all")) {
528
+ results.playlists = await db.playlist.find({
529
+ $or: [{ title: searchRegex }, { description: searchRegex }, { tags: searchRegex }],
530
+ isPublic: true
531
+ }).limit(limitNum);
532
+ }
533
+ if (types.includes("genres") || types.includes("all")) {
534
+ results.genres = await db.genre.find({
535
+ $or: [{ name: searchRegex }, { description: searchRegex }],
536
+ status: "published"
537
+ }).limit(limitNum);
538
+ }
539
+ await cache.set(cacheKey, results, 600);
540
+ }
541
+ res.json(results);
542
+ } catch (error) {
543
+ logger.error(`Error searching: ${error.message}`);
544
+ res.status(500).json({ error: error.message });
545
+ }
546
+ }
547
+ return {
548
+ search
549
+ };
550
+ };
551
+ const StreamController = function(app, db, publicPath) {
552
+ const { getInstance: getInstance2 } = globals_abac.globalsabac;
553
+ const logger = new globals_logger.Logger(db);
554
+ const abac = getInstance2(db);
555
+ async function streamAudio(req, res) {
556
+ try {
557
+ const trackId = req.params.trackId;
558
+ const track = await db.track.findById(trackId);
559
+ if (!track) {
560
+ return res.status(404).json({ error: "Track not found" });
561
+ }
562
+ const accessResult = await abac.checkAccess({
563
+ user: req.userId,
564
+ resource: "tracks",
565
+ action: "read",
566
+ currentResource: track
567
+ });
568
+ if (!accessResult.allowed && !track.isPublic) {
569
+ return res.status(403).json({
570
+ errorCode: accessResult.reason,
571
+ message: "Access Denied"
572
+ });
573
+ }
574
+ const fileUrl = track.fileUrl;
575
+ console.log("public is", publicPath);
576
+ const filePath = path$1.join(publicPath, fileUrl);
577
+ if (!fs$1.existsSync(filePath)) {
578
+ logger.error(`File not found: ${filePath}`);
579
+ return res.status(404).json({ error: "Audio file not found" });
580
+ }
581
+ const stat = fs$1.statSync(filePath);
582
+ const fileSize = stat.size;
583
+ const range = req.headers.range;
584
+ if (req.userId) {
585
+ try {
586
+ await db.playHistory.create({
587
+ user: req.userId,
588
+ track: trackId,
589
+ playedAt: /* @__PURE__ */ new Date(),
590
+ deviceInfo: req.headers["user-agent"],
591
+ playedFrom: req.query.from || "other",
592
+ contextId: req.query.contextId || null
593
+ });
594
+ await db.track.findByIdAndUpdate(trackId, { $inc: { playCount: 1 } });
595
+ } catch (error) {
596
+ logger.error(`Error logging play history: ${error.message}`);
597
+ }
598
+ }
599
+ if (range) {
600
+ const parts = range.replace(/bytes=/, "").split("-");
601
+ const start = parseInt(parts[0], 10);
602
+ const end = parts[1] ? parseInt(parts[1], 10) : fileSize - 1;
603
+ const chunksize = end - start + 1;
604
+ const file = fs$1.createReadStream(filePath, { start, end });
605
+ res.writeHead(206, {
606
+ "Content-Range": `bytes ${start}-${end}/${fileSize}`,
607
+ "Accept-Ranges": "bytes",
608
+ "Content-Length": chunksize,
609
+ "Content-Type": "audio/mpeg"
610
+ });
611
+ file.pipe(res);
612
+ } else {
613
+ res.writeHead(200, {
614
+ "Content-Length": fileSize,
615
+ "Content-Type": "audio/mpeg"
616
+ });
617
+ fs$1.createReadStream(filePath).pipe(res);
618
+ }
619
+ } catch (error) {
620
+ logger.error(`Error streaming audio: ${error.message}`);
621
+ res.status(500).json({ error: error.message });
622
+ }
623
+ }
624
+ return {
625
+ streamAudio
626
+ };
627
+ };
628
+ const AlbumModel = function(db) {
629
+ const albumSchema = new db.mongoose.Schema(
630
+ {
631
+ title: {
632
+ type: String,
633
+ required: true
634
+ },
635
+ description: {
636
+ type: String,
637
+ default: ""
638
+ },
639
+ releaseDate: {
640
+ type: Date,
641
+ required: true
642
+ },
643
+ coverArt: {
644
+ type: String,
645
+ default: null
646
+ },
647
+ artists: [
648
+ {
649
+ type: db.mongoose.Schema.Types.ObjectId,
650
+ ref: "Artist",
651
+ required: true
652
+ }
653
+ ],
654
+ type: {
655
+ type: String,
656
+ enum: ["album", "single", "EP", "compilation"],
657
+ default: "album"
658
+ },
659
+ genres: [
660
+ {
661
+ type: db.mongoose.Schema.Types.ObjectId,
662
+ ref: "Genre"
663
+ }
664
+ ],
665
+ totalTracks: {
666
+ type: Number,
667
+ default: 0
668
+ }
669
+ },
670
+ {
671
+ timestamps: true,
672
+ versionKey: false
673
+ }
674
+ );
675
+ ownership_schema.applyOwnershipSchema(albumSchema, db);
676
+ metadata_schema.applyMetadataSchema(albumSchema);
677
+ common_schema.applyCommonSchema(albumSchema);
678
+ engagement_schema.applyEngagementSchema(albumSchema);
679
+ albumSchema.index({ title: "text", description: "text" });
680
+ albumSchema.index({ artists: 1 });
681
+ albumSchema.index({ releaseDate: -1 });
682
+ albumSchema.index({ type: 1 });
683
+ albumSchema.index({ genres: 1 });
684
+ return db.mongoose.models.Album || db.mongoose.model("Album", albumSchema);
685
+ };
686
+ const ArtistModel = function(db) {
687
+ const mongoose = db.mongoose;
688
+ const Schema = mongoose.Schema;
689
+ const ArtistSchema = new Schema(
690
+ {
691
+ name: {
692
+ type: String,
693
+ required: true,
694
+ trim: true
695
+ },
696
+ bio: {
697
+ type: String,
698
+ trim: true
699
+ },
700
+ photoUrl: {
701
+ type: String
702
+ },
703
+ coverUrl: {
704
+ type: String
705
+ },
706
+ genre: [
707
+ {
708
+ type: Schema.Types.ObjectId,
709
+ ref: "Genre"
710
+ }
711
+ ],
712
+ isVerified: {
713
+ type: Boolean,
714
+ default: false
715
+ },
716
+ website: {
717
+ type: String,
718
+ trim: true
719
+ },
720
+ location: {
721
+ type: String,
722
+ trim: true
723
+ },
724
+ popularity: {
725
+ type: Number,
726
+ default: 0
727
+ }
728
+ },
729
+ {
730
+ timestamps: true,
731
+ versionKey: false
732
+ }
733
+ );
734
+ common_schema.applyCommonSchema(ArtistSchema);
735
+ metadata_schema.applyMetadataSchema(ArtistSchema);
736
+ ownership_schema.applyOwnershipSchema(ArtistSchema, db);
737
+ socials_schema.applySocialsSchema(ArtistSchema);
738
+ engagement_schema.applyEngagementSchema(ArtistSchema);
739
+ ArtistSchema.index({ name: "text", bio: "text" });
740
+ ArtistSchema.index({ popularity: -1 });
741
+ ArtistSchema.index({ isVerified: 1 });
742
+ return mongoose.models.Artist || mongoose.model("Artist", ArtistSchema);
743
+ };
744
+ const GenreModel = function(db) {
745
+ const mongoose = db.mongoose;
746
+ const Schema = mongoose.Schema;
747
+ const GenreSchema = new Schema(
748
+ {
749
+ name: {
750
+ type: String,
751
+ required: true,
752
+ trim: true,
753
+ unique: true
754
+ },
755
+ description: {
756
+ type: String,
757
+ trim: true
758
+ },
759
+ iconUrl: {
760
+ type: String
761
+ },
762
+ popularity: {
763
+ type: Number,
764
+ default: 0
765
+ }
766
+ },
767
+ {
768
+ timestamps: true,
769
+ versionKey: false
770
+ }
771
+ );
772
+ common_schema.applyCommonSchema(GenreSchema);
773
+ metadata_schema.applyMetadataSchema(GenreSchema);
774
+ GenreSchema.index({ name: "text", description: "text" });
775
+ GenreSchema.index({ popularity: -1 });
776
+ return mongoose.models.Genre || mongoose.model("Genre", GenreSchema);
777
+ };
778
+ const PlayHistoryModel = function(db) {
779
+ const mongoose = db.mongoose;
780
+ const Schema = mongoose.Schema;
781
+ const PlayHistorySchema = new Schema(
782
+ {
783
+ user: {
784
+ type: Schema.Types.ObjectId,
785
+ ref: "User",
786
+ required: true
787
+ },
788
+ track: {
789
+ type: Schema.Types.ObjectId,
790
+ ref: "Track",
791
+ required: true
792
+ },
793
+ playedAt: {
794
+ type: Date,
795
+ default: Date.now
796
+ },
797
+ playDuration: {
798
+ type: Number,
799
+ default: 0
800
+ },
801
+ playedFrom: {
802
+ type: String,
803
+ enum: ["playlist", "album", "search", "recommendation", "artist", "other"],
804
+ default: "other"
805
+ },
806
+ contextId: {
807
+ type: Schema.Types.ObjectId,
808
+ refPath: "playedFrom"
809
+ },
810
+ deviceInfo: {
811
+ type: String
812
+ },
813
+ location: {
814
+ type: String
815
+ }
816
+ },
817
+ {
818
+ timestamps: true,
819
+ versionKey: false
820
+ }
821
+ );
822
+ PlayHistorySchema.index({ user: 1, playedAt: -1 });
823
+ PlayHistorySchema.index({ track: 1 });
824
+ PlayHistorySchema.index({ playedAt: -1 });
825
+ return mongoose.models.PlayHistory || mongoose.model("PlayHistory", PlayHistorySchema);
826
+ };
827
+ const PlaylistModel = function(db) {
828
+ const mongoose = db.mongoose;
829
+ const Schema = mongoose.Schema;
830
+ const PlaylistSchema = new Schema(
831
+ {
832
+ title: {
833
+ type: String,
834
+ required: true,
835
+ trim: true
836
+ },
837
+ description: {
838
+ type: String,
839
+ trim: true
840
+ },
841
+ coverUrl: {
842
+ type: String
843
+ },
844
+ tracks: [
845
+ {
846
+ track: {
847
+ type: Schema.Types.ObjectId,
848
+ ref: "Track"
849
+ },
850
+ addedAt: {
851
+ type: Date,
852
+ default: Date.now
853
+ }
854
+ }
855
+ ],
856
+ isPublic: {
857
+ type: Boolean,
858
+ default: true
859
+ },
860
+ followers: {
861
+ type: Number,
862
+ default: 0
863
+ },
864
+ isCollaborative: {
865
+ type: Boolean,
866
+ default: false
867
+ },
868
+ collaborators: [
869
+ {
870
+ type: Schema.Types.ObjectId,
871
+ ref: "User"
872
+ }
873
+ ]
874
+ },
875
+ {
876
+ timestamps: true,
877
+ versionKey: false
878
+ }
879
+ );
880
+ common_schema.applyCommonSchema(PlaylistSchema);
881
+ metadata_schema.applyMetadataSchema(PlaylistSchema);
882
+ ownership_schema.applyOwnershipSchema(PlaylistSchema, db);
883
+ engagement_schema.applyEngagementSchema(PlaylistSchema);
884
+ PlaylistSchema.index({ title: "text", description: "text" });
885
+ PlaylistSchema.index({ isPublic: 1 });
886
+ PlaylistSchema.index({ followers: -1 });
887
+ PlaylistSchema.index({ "tracks.addedAt": -1 });
888
+ return mongoose.models.Playlist || mongoose.model("Playlist", PlaylistSchema);
889
+ };
890
+ const TrackModel = function(db) {
891
+ const mongoose = db.mongoose;
892
+ const Schema = mongoose.Schema;
893
+ const TrackSchema = new Schema(
894
+ {
895
+ title: {
896
+ type: String,
897
+ required: true,
898
+ trim: true
899
+ },
900
+ artist: {
901
+ type: Schema.Types.ObjectId,
902
+ ref: "Artist",
903
+ required: true
904
+ },
905
+ album: {
906
+ type: Schema.Types.ObjectId,
907
+ ref: "Album"
908
+ },
909
+ duration: {
910
+ type: Number,
911
+ default: 0
912
+ },
913
+ fileUrl: {
914
+ type: String,
915
+ required: true
916
+ },
917
+ coverUrl: {
918
+ type: String
919
+ },
920
+ genre: [
921
+ {
922
+ type: Schema.Types.ObjectId,
923
+ ref: "Genre"
924
+ }
925
+ ],
926
+ releaseDate: {
927
+ type: Date,
928
+ default: Date.now
929
+ },
930
+ isExplicit: {
931
+ type: Boolean,
932
+ default: false
933
+ },
934
+ lyrics: {
935
+ type: String
936
+ },
937
+ playCount: {
938
+ type: Number,
939
+ default: 0
940
+ },
941
+ isPublic: {
942
+ type: Boolean,
943
+ default: true
944
+ }
945
+ },
946
+ {
947
+ timestamps: true,
948
+ versionKey: false
949
+ }
950
+ );
951
+ common_schema.applyCommonSchema(TrackSchema);
952
+ metadata_schema.applyMetadataSchema(TrackSchema);
953
+ ownership_schema.applyOwnershipSchema(TrackSchema, db);
954
+ engagement_schema.applyEngagementSchema(TrackSchema);
955
+ TrackSchema.index({ title: "text" });
956
+ TrackSchema.index({ artist: 1 });
957
+ TrackSchema.index({ album: 1 });
958
+ TrackSchema.index({ releaseDate: -1 });
959
+ TrackSchema.index({ playCount: -1 });
960
+ TrackSchema.pre("save", function(next) {
961
+ if (!this.url) {
962
+ this.url = metadata_schema.createFriendlyURL(`${this.title}-${this._id}`);
963
+ }
964
+ next();
965
+ });
966
+ TrackSchema.virtual("artistName").get(function() {
967
+ return this.artist ? this.artist.name : "";
968
+ });
969
+ return mongoose.models.Track || mongoose.model("Track", TrackSchema);
970
+ };
971
+ const musicPolicies = function initializeMusicPolicies(abacAccessControl) {
972
+ abacAccessControl.registerResourcePolicy("tracks", async (context) => {
973
+ const { user, action, currentResource, resourceModel } = context;
974
+ const ObjectId = abacAccessControl.db.mongoose.Types.ObjectId;
975
+ if (action === "read" && currentResource?.status === "published" && currentResource?.isPublic === true) {
976
+ return true;
977
+ }
978
+ if (action === "create") {
979
+ if (context.data.creator && context.data.creator.target) {
980
+ return context.data.creator.target.toString() === user.toString();
981
+ }
982
+ return false;
983
+ }
984
+ if (["update", "edit", "delete"].includes(action) && currentResource) {
985
+ if (currentResource.owner && currentResource.owner.type === "Organization") {
986
+ const Organization = abacAccessControl.db.organization;
987
+ const org = await Organization.findOne({
988
+ _id: currentResource.owner.target,
989
+ members: { $elemMatch: { user: new ObjectId(user) } }
990
+ });
991
+ if (org) return true;
992
+ }
993
+ if (currentResource.creator && currentResource.creator.target && currentResource.creator.target.toString() === user.toString()) {
994
+ return true;
995
+ }
996
+ return false;
997
+ }
998
+ return false;
999
+ });
1000
+ abacAccessControl.registerResourcePolicy("albums", async (context) => {
1001
+ return abacAccessControl.policies.resources.tracks(context);
1002
+ });
1003
+ abacAccessControl.registerResourcePolicy("playlists", async (context) => {
1004
+ const { user, action, currentResource } = context;
1005
+ if (currentResource && currentResource.isCollaborative && currentResource.collaborators && currentResource.collaborators.some((collaborator) => collaborator.toString() === user.toString())) {
1006
+ if (action === "edit" || action === "update") {
1007
+ return true;
1008
+ }
1009
+ }
1010
+ return abacAccessControl.policies.resources.tracks(context);
1011
+ });
1012
+ abacAccessControl.registerResourcePolicy("artists", async (context) => {
1013
+ return abacAccessControl.policies.resources.tracks(context);
1014
+ });
1015
+ return abacAccessControl;
1016
+ };
1017
+ const albumRoutes = function(app, db, origins, publicPath) {
1018
+ const controller = AlbumController(app, db);
1019
+ const { authJwt } = index.middlewareIndexFactory(db);
1020
+ app.post("/api/albums/create", [authJwt.verifyToken], controller.create);
1021
+ app.get("/api/albums/read", controller.read);
1022
+ app.put("/api/albums/update", [authJwt.verifyToken], controller.update);
1023
+ app.delete("/api/albums/delete", [authJwt.verifyToken], controller.delete);
1024
+ app.get("/api/albums/:albumId/tracks", controller.getAlbumTracks);
1025
+ app.get("/api/albums/featured", controller.getFeaturedAlbums);
1026
+ app.get("/api/albums/url/:url", async (req, res) => {
1027
+ try {
1028
+ const album = await db.album.findOne({ url: req.params.url }).populate("artist");
1029
+ if (!album) {
1030
+ return res.status(404).json({ error: "Album not found" });
1031
+ }
1032
+ res.json(album);
1033
+ } catch (error) {
1034
+ console.error(error);
1035
+ res.status(500).json({ error: error.message });
1036
+ }
1037
+ });
1038
+ };
1039
+ const artistRoutes = function(app, db, origins, publicPath) {
1040
+ const controller = ArtistController(app, db);
1041
+ const { authJwt } = index.middlewareIndexFactory(db);
1042
+ app.post("/api/artists/create", [authJwt.verifyToken], controller.create);
1043
+ app.get("/api/artists/read", controller.read);
1044
+ app.put("/api/artists/update", [authJwt.verifyToken], controller.update);
1045
+ app.delete("/api/artists/delete", [authJwt.verifyToken], controller.delete);
1046
+ app.get("/api/artists/:artistId/discography", controller.getDiscography);
1047
+ app.put("/api/artists/:artistId/verify", [authJwt.verifyToken, authJwt.isAdmin], controller.verifyArtist);
1048
+ app.get("/api/artists/:artistId/related", controller.getRelatedArtists);
1049
+ app.get("/api/artists/url/:url", async (req, res) => {
1050
+ try {
1051
+ const artist = await db.artist.findOne({ url: req.params.url });
1052
+ if (!artist) {
1053
+ return res.status(404).json({ error: "Artist not found" });
1054
+ }
1055
+ res.json(artist);
1056
+ } catch (error) {
1057
+ console.error(error);
1058
+ res.status(500).json({ error: error.message });
1059
+ }
1060
+ });
1061
+ };
1062
+ const genreRoutes = function(app, db, origins, publicPath) {
1063
+ const controller = GenreController(app, db);
1064
+ const { authJwt } = index.middlewareIndexFactory(db);
1065
+ app.post("/api/genres/create", [authJwt.verifyToken, authJwt.isAdmin], controller.create);
1066
+ app.get("/api/genres/read", controller.read);
1067
+ app.put("/api/genres/update", [authJwt.verifyToken, authJwt.isAdmin], controller.update);
1068
+ app.delete("/api/genres/delete", [authJwt.verifyToken, authJwt.isAdmin], controller.delete);
1069
+ app.get("/api/genres/:genreId/tracks", controller.getGenreTracks);
1070
+ app.get("/api/genres/popular", controller.getPopularGenres);
1071
+ app.get("/api/genres/url/:url", async (req, res) => {
1072
+ try {
1073
+ const genre = await db.genre.findOne({ url: req.params.url });
1074
+ if (!genre) {
1075
+ return res.status(404).json({ error: "Genre not found" });
1076
+ }
1077
+ res.json(genre);
1078
+ } catch (error) {
1079
+ console.error(error);
1080
+ res.status(500).json({ error: error.message });
1081
+ }
1082
+ });
1083
+ };
1084
+ const { getInstance } = globals_abac.globalsabac;
1085
+ const musicRoutes = function(app, db, origins, publicPath) {
1086
+ const { MusicController: MusicController$1 } = MusicController(app, db);
1087
+ const { authJwt } = index.middlewareIndexFactory(db);
1088
+ const controller = new MusicController$1("/api/tracks", app, db, db.track, {
1089
+ disableDefaultRoutes: true
1090
+ });
1091
+ const abac = getInstance(db);
1092
+ app.post(
1093
+ "/api/tracks/create",
1094
+ [
1095
+ authJwt.verifyToken(),
1096
+ // Auth middleware
1097
+ (req, res, next) => {
1098
+ console.log("[Route] /api/tracks/create - Request received");
1099
+ console.log("[Route] User ID from token:", req.userId);
1100
+ next();
1101
+ }
1102
+ ],
1103
+ controller.create.bind(controller)
1104
+ // Bind to ensure 'this' context
1105
+ );
1106
+ app.get("/api/tracks/read", controller.read.bind(controller));
1107
+ app.put("/api/tracks/update", [authJwt.verifyToken], controller.update.bind(controller));
1108
+ app.delete("/api/tracks/delete", [authJwt.verifyToken], controller.delete.bind(controller));
1109
+ app.get("/api/tracks/url/:url", async (req, res) => {
1110
+ try {
1111
+ const track = await db.track.findOne({ url: req.params.url });
1112
+ if (!track) {
1113
+ return res.status(404).json({ error: "Track not found" });
1114
+ }
1115
+ const accessResult = await abac.checkAccess({
1116
+ user: req.userId,
1117
+ resource: "tracks",
1118
+ action: "read",
1119
+ currentResource: track
1120
+ });
1121
+ if (!accessResult.allowed && !track.isPublic) {
1122
+ return res.status(403).json({
1123
+ errorCode: accessResult.reason,
1124
+ message: "Access Denied"
1125
+ });
1126
+ }
1127
+ res.json(track);
1128
+ } catch (error) {
1129
+ console.error(error);
1130
+ res.status(500).json({ error: error.message });
1131
+ }
1132
+ });
1133
+ app.get("/api/tracks/recent", async (req, res) => {
1134
+ try {
1135
+ const limit = parseInt(req.query.limit) || 10;
1136
+ const recentTracks = await db.track.find({
1137
+ status: "published",
1138
+ isPublic: true
1139
+ }).sort({ createdAt: -1 }).limit(limit);
1140
+ res.json(recentTracks);
1141
+ } catch (error) {
1142
+ console.error(error);
1143
+ res.status(500).json({ error: error.message });
1144
+ }
1145
+ });
1146
+ app.get("/api/tracks/popular", async (req, res) => {
1147
+ try {
1148
+ const limit = parseInt(req.query.limit) || 10;
1149
+ const popularTracks = await db.track.find({
1150
+ status: "published",
1151
+ isPublic: true
1152
+ }).sort({ playCount: -1 }).limit(limit);
1153
+ res.json(popularTracks);
1154
+ } catch (error) {
1155
+ console.error(error);
1156
+ res.status(500).json({ error: error.message });
1157
+ }
1158
+ });
1159
+ app.get("/api/tracks/genre/:genreId", async (req, res) => {
1160
+ try {
1161
+ const tracks = await db.track.find({
1162
+ genre: req.params.genreId,
1163
+ status: "published",
1164
+ isPublic: true
1165
+ }).sort({ releaseDate: -1 });
1166
+ res.json(tracks);
1167
+ } catch (error) {
1168
+ console.error(error);
1169
+ res.status(500).json({ error: error.message });
1170
+ }
1171
+ });
1172
+ };
1173
+ const playlistRoutes = function(app, db, origins, publicPath) {
1174
+ const controller = PlaylistController(app, db);
1175
+ const { authJwt } = index.middlewareIndexFactory(db);
1176
+ app.post("/api/playlists/create", [authJwt.verifyToken], controller.create);
1177
+ app.get("/api/playlists/read", controller.read);
1178
+ app.put("/api/playlists/update", [authJwt.verifyToken], controller.update);
1179
+ app.delete("/api/playlists/delete", [authJwt.verifyToken], controller.delete);
1180
+ app.get("/api/playlists/user/:userId?", [authJwt.verifyToken], controller.getUserPlaylists);
1181
+ app.post("/api/playlists/:playlistId/tracks/:trackId", [authJwt.verifyToken], controller.addTrack);
1182
+ app.delete("/api/playlists/:playlistId/tracks/:trackId", [authJwt.verifyToken], controller.removeTrack);
1183
+ app.post("/api/playlists/:playlistId/collaborators/:userId", [authJwt.verifyToken], controller.addCollaborator);
1184
+ app.get("/api/playlists/url/:url", async (req, res) => {
1185
+ try {
1186
+ const playlist = await db.playlist.findOne({ url: req.params.url }).populate({
1187
+ path: "tracks.track",
1188
+ select: "-lyrics"
1189
+ });
1190
+ if (!playlist) {
1191
+ return res.status(404).json({ error: "Playlist not found" });
1192
+ }
1193
+ if (!playlist.isPublic) {
1194
+ if (!req.userId) {
1195
+ return res.status(403).json({ error: "Access denied to private playlist" });
1196
+ }
1197
+ const isOwner = playlist.owner.target.toString() === req.userId;
1198
+ const isCollaborator = playlist.collaborators.some((collab) => collab.toString() === req.userId);
1199
+ if (!isOwner && !isCollaborator) {
1200
+ return res.status(403).json({ error: "Access denied to private playlist" });
1201
+ }
1202
+ }
1203
+ res.json(playlist);
1204
+ } catch (error) {
1205
+ console.error(error);
1206
+ res.status(500).json({ error: error.message });
1207
+ }
1208
+ });
1209
+ };
1210
+ const searchRoutes = function(app, db, origins, publicPath) {
1211
+ const controller = SearchController(app, db);
1212
+ app.get("/api/music/search", controller.search);
1213
+ };
1214
+ const streamRoutes = function(app, db, origins, publicPath) {
1215
+ console.log("rouus publioc is", publicPath);
1216
+ const controller = StreamController(app, db, publicPath);
1217
+ app.get("/api/stream/:trackId", controller.streamAudio);
1218
+ app.get("/api/waveform/:trackId", async (req, res) => {
1219
+ try {
1220
+ const track = await db.track.findById(req.params.trackId);
1221
+ if (!track) {
1222
+ return res.status(404).json({ error: "Track not found" });
1223
+ }
1224
+ const waveformPath = path.join(process.env.FILE_STORAGE_PATH || "./uploads", `waveforms/${track._id}.json`);
1225
+ if (fs.existsSync(waveformPath)) {
1226
+ const waveformData = JSON.parse(fs.readFileSync(waveformPath, "utf8"));
1227
+ return res.json(waveformData);
1228
+ }
1229
+ res.status(404).json({ error: "Waveform data not found" });
1230
+ } catch (error) {
1231
+ console.error(error);
1232
+ res.status(500).json({ error: error.message });
1233
+ }
1234
+ });
1235
+ };
1236
+ const StreamingHandler = function(db) {
1237
+ const logger = new globals_logger.Logger(db);
1238
+ return {
1239
+ // Handle WebSocket messages for music streaming
1240
+ handleStreamingMessage: async (ws, message) => {
1241
+ try {
1242
+ const { action, data } = message;
1243
+ switch (action) {
1244
+ case "startPlaying":
1245
+ if (ws.userId && data.trackId) {
1246
+ await db.playHistory.create({
1247
+ user: ws.userId,
1248
+ track: data.trackId,
1249
+ playedAt: /* @__PURE__ */ new Date(),
1250
+ deviceInfo: data.deviceInfo || "Unknown",
1251
+ playedFrom: data.from || "other",
1252
+ contextId: data.contextId || null
1253
+ });
1254
+ await db.track.findByIdAndUpdate(data.trackId, { $inc: { playCount: 1 } });
1255
+ ws.send(
1256
+ JSON.stringify({
1257
+ type: "playAcknowledged",
1258
+ trackId: data.trackId
1259
+ })
1260
+ );
1261
+ }
1262
+ break;
1263
+ case "syncPosition":
1264
+ if (ws.userId && data.trackId && data.position) {
1265
+ const latestPlay = await db.playHistory.findOne({
1266
+ user: ws.userId,
1267
+ track: data.trackId
1268
+ }).sort({ playedAt: -1 });
1269
+ if (latestPlay) {
1270
+ latestPlay.playDuration = data.position;
1271
+ await latestPlay.save();
1272
+ }
1273
+ }
1274
+ break;
1275
+ case "getRecommendations":
1276
+ if (ws.userId) {
1277
+ const recentTracks = await db.playHistory.find({
1278
+ user: ws.userId
1279
+ }).sort({ playedAt: -1 }).limit(10).populate("track");
1280
+ const recentGenres = /* @__PURE__ */ new Set();
1281
+ const recentArtists = /* @__PURE__ */ new Set();
1282
+ recentTracks.forEach((history) => {
1283
+ if (history.track) {
1284
+ if (history.track.genre) {
1285
+ history.track.genre.forEach((g) => recentGenres.add(g.toString()));
1286
+ }
1287
+ if (history.track.artist) {
1288
+ recentArtists.add(history.track.artist.toString());
1289
+ }
1290
+ }
1291
+ });
1292
+ const recommendations = await db.track.find({
1293
+ $or: [{ genre: { $in: Array.from(recentGenres) } }, { artist: { $in: Array.from(recentArtists) } }],
1294
+ _id: { $nin: recentTracks.map((h) => h.track._id) },
1295
+ // Exclude recently played
1296
+ status: "published",
1297
+ isPublic: true
1298
+ }).limit(10).populate("artist", "name").populate("album", "title coverUrl");
1299
+ ws.send(
1300
+ JSON.stringify({
1301
+ type: "recommendations",
1302
+ tracks: recommendations
1303
+ })
1304
+ );
1305
+ }
1306
+ break;
1307
+ case "joinListeningParty":
1308
+ if (ws.userId && data.partyId) {
1309
+ ws.listeningParty = data.partyId;
1310
+ global.webSocketManager.broadcastToModuleWithFilter("music-streaming", (socket) => socket.listeningParty === data.partyId, {
1311
+ type: "partyMemberJoined",
1312
+ userId: ws.userId,
1313
+ partyId: data.partyId
1314
+ });
1315
+ }
1316
+ break;
1317
+ case "syncPartyPlayback":
1318
+ if (ws.userId && ws.listeningParty && data.trackId && data.position) {
1319
+ global.webSocketManager.broadcastToModuleWithFilter("music-streaming", (socket) => socket.listeningParty === ws.listeningParty && socket !== ws, {
1320
+ type: "partyPlaybackSync",
1321
+ trackId: data.trackId,
1322
+ position: data.position,
1323
+ isPlaying: data.isPlaying,
1324
+ timestamp: Date.now()
1325
+ });
1326
+ }
1327
+ break;
1328
+ default:
1329
+ logger.info(`Unknown streaming action: ${action}`);
1330
+ }
1331
+ } catch (error) {
1332
+ logger.error(`Error in streaming handler: ${error.message}`);
1333
+ ws.send(
1334
+ JSON.stringify({
1335
+ type: "error",
1336
+ message: "An error occurred while processing your request"
1337
+ })
1338
+ );
1339
+ }
1340
+ }
1341
+ };
1342
+ };
1343
+ function initializeMusic({ app, db, wss, origins, publicPath }) {
1344
+ db.track = TrackModel(db);
1345
+ db.playlist = PlaylistModel(db);
1346
+ db.album = AlbumModel(db);
1347
+ db.artist = ArtistModel(db);
1348
+ db.genre = GenreModel(db);
1349
+ db.playHistory = PlayHistoryModel(db);
1350
+ console.log("server publioc is", publicPath);
1351
+ if (app) {
1352
+ musicRoutes(app, db);
1353
+ playlistRoutes(app, db);
1354
+ albumRoutes(app, db);
1355
+ artistRoutes(app, db);
1356
+ streamRoutes(app, db, origins, publicPath);
1357
+ searchRoutes(app, db);
1358
+ genreRoutes(app, db);
1359
+ }
1360
+ const { getInstance: getInstance2 } = globals_abac.globalsabac;
1361
+ const abac = getInstance2(db);
1362
+ musicPolicies(abac);
1363
+ const { WebSocketManager } = globals_websocket.WebSocketManager;
1364
+ if (global.webSocketManager && global.webSocketManager instanceof WebSocketManager) {
1365
+ global.webSocketManager.registerModule("music-streaming", StreamingHandler(db).handleStreamingMessage);
1366
+ }
1367
+ new globals_logger.Cache({ ttlSeconds: 60 * 15 });
1368
+ const musicLogger = new globals_logger.Logger(db);
1369
+ musicLogger.info("Music module initialized");
1370
+ }
1371
+ const models = {
1372
+ TrackModel,
1373
+ PlaylistModel,
1374
+ AlbumModel,
1375
+ ArtistModel,
1376
+ GenreModel,
1377
+ PlayHistoryModel
1378
+ };
1379
+ const routes = {
1380
+ musicRoutes,
1381
+ playlistRoutes,
1382
+ albumRoutes,
1383
+ artistRoutes,
1384
+ streamRoutes,
1385
+ searchRoutes,
1386
+ genreRoutes
1387
+ };
1388
+ const controllers = {
1389
+ MusicController,
1390
+ PlaylistController,
1391
+ AlbumController,
1392
+ ArtistController,
1393
+ StreamController,
1394
+ SearchController,
1395
+ GenreController
1396
+ };
1397
+ const music_server = {
1398
+ initialize: initializeMusic,
1399
+ models,
1400
+ routes,
1401
+ controllers
1402
+ };
1403
+ exports.controllers = controllers;
1404
+ exports.default = music_server;
1405
+ exports.initialize = initializeMusic;
1406
+ exports.models = models;
1407
+ exports.routes = routes;