@ozdao/martyrs 0.2.470 → 0.2.472
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.
- package/dist/{Media-CR0V1zvB.js → Media-DW8RLbfM.js} +1 -1
- package/dist/{Media-C4Ges_Sd.mjs → Media-y_TX6us_.mjs} +1 -1
- package/dist/_virtual/index.cjs +1 -1
- package/dist/_virtual/index.js +1 -1
- package/dist/auth.server.js +1 -1
- package/dist/auth.server.mjs +1 -1
- package/dist/chats.server.js +1 -1
- package/dist/chats.server.mjs +1 -1
- package/dist/community.server.js +1 -1
- package/dist/community.server.mjs +1 -1
- package/dist/events.server.js +1 -1
- package/dist/events.server.mjs +1 -1
- package/dist/files.server.js +1 -1
- package/dist/files.server.mjs +1 -1
- package/dist/gallery.server.js +1 -1
- package/dist/gallery.server.mjs +1 -1
- package/dist/{index-DQqZReAr.js → index-CVXl1rB5.js} +0 -1
- package/dist/{index-DICZTQ-1.mjs → index-Df8vtZx7.mjs} +0 -1
- package/dist/{main-CsZAG5Wz.js → main-CCfQH-Dd.js} +2 -2
- package/dist/{main-CTcal9qN.mjs → main-CgmHzhq5.mjs} +74 -74
- package/dist/{node_modules/.pnpm/@vue_server-renderer@3.5.13_vue@3.5.13_typescript@5.8.3_ → martyrs}/node_modules/@vue/server-renderer/dist/server-renderer.esm-bundler.cjs +1 -1
- package/dist/martyrs/node_modules/@vue/server-renderer/dist/server-renderer.esm-bundler.cjs.map +1 -0
- package/dist/{node_modules/.pnpm/@vue_server-renderer@3.5.13_vue@3.5.13_typescript@5.8.3_ → martyrs}/node_modules/@vue/server-renderer/dist/server-renderer.esm-bundler.js +1 -1
- package/dist/martyrs/node_modules/@vue/server-renderer/dist/server-renderer.esm-bundler.js.map +1 -0
- package/dist/martyrs/node_modules/@vue/shared/dist/shared.esm-bundler.cjs.map +1 -0
- package/dist/martyrs/node_modules/@vue/shared/dist/shared.esm-bundler.js.map +1 -0
- package/dist/martyrs/node_modules/uuid/dist/esm-browser/regex.cjs +5 -0
- package/dist/martyrs/node_modules/uuid/dist/esm-browser/regex.cjs.map +1 -0
- package/dist/martyrs/node_modules/uuid/dist/esm-browser/regex.js +5 -0
- package/dist/martyrs/node_modules/uuid/dist/esm-browser/regex.js.map +1 -0
- package/dist/{node_modules/.pnpm/uuid@11.1.0 → martyrs}/node_modules/uuid/dist/esm-browser/rng.cjs +4 -4
- package/dist/martyrs/node_modules/uuid/dist/esm-browser/rng.cjs.map +1 -0
- package/dist/martyrs/node_modules/uuid/dist/esm-browser/rng.js +15 -0
- package/dist/martyrs/node_modules/uuid/dist/esm-browser/rng.js.map +1 -0
- package/dist/martyrs/node_modules/uuid/dist/esm-browser/stringify.cjs +17 -0
- package/dist/martyrs/node_modules/uuid/dist/esm-browser/stringify.cjs.map +1 -0
- package/dist/martyrs/node_modules/uuid/dist/esm-browser/stringify.js +17 -0
- package/dist/martyrs/node_modules/uuid/dist/esm-browser/stringify.js.map +1 -0
- package/dist/martyrs/node_modules/uuid/dist/esm-browser/v4.cjs +13 -0
- package/dist/martyrs/node_modules/uuid/dist/esm-browser/v4.cjs.map +1 -0
- package/dist/martyrs/node_modules/uuid/dist/esm-browser/v4.js +13 -0
- package/dist/martyrs/node_modules/uuid/dist/esm-browser/v4.js.map +1 -0
- package/dist/martyrs/node_modules/uuid/dist/esm-browser/validate.cjs +8 -0
- package/dist/martyrs/node_modules/uuid/dist/esm-browser/validate.cjs.map +1 -0
- package/dist/martyrs/node_modules/uuid/dist/esm-browser/validate.js +8 -0
- package/dist/martyrs/node_modules/uuid/dist/esm-browser/validate.js.map +1 -0
- package/dist/martyrs/src/components/Feed/Feed.vue.cjs +2 -2
- package/dist/martyrs/src/components/Feed/Feed.vue.cjs.map +1 -1
- package/dist/martyrs/src/components/Feed/Feed.vue.js +2 -2
- package/dist/martyrs/src/components/Feed/Feed.vue.js.map +1 -1
- package/dist/martyrs/src/components/Menu/{Menu.vue.cjs → Menu.vue2.cjs} +2 -2
- package/dist/martyrs/src/components/Menu/Menu.vue2.cjs.map +1 -0
- package/dist/martyrs/src/components/Menu/{Menu.vue.js → Menu.vue2.js} +2 -2
- package/dist/martyrs/src/components/Menu/Menu.vue2.js.map +1 -0
- package/dist/martyrs/src/components/Skeleton/Skeleton.vue.cjs +5 -5
- package/dist/martyrs/src/components/Skeleton/Skeleton.vue.cjs.map +1 -1
- package/dist/martyrs/src/components/Skeleton/Skeleton.vue.js +5 -5
- package/dist/martyrs/src/components/Skeleton/Skeleton.vue.js.map +1 -1
- package/dist/martyrs/src/components/Tab/{Tab.vue2.cjs → Tab.vue.cjs} +2 -2
- package/dist/martyrs/src/components/Tab/{Tab.vue2.js.map → Tab.vue.cjs.map} +1 -1
- package/dist/martyrs/src/components/Tab/{Tab.vue2.js → Tab.vue.js} +2 -2
- package/dist/martyrs/src/components/Tab/Tab.vue.js.map +1 -0
- package/dist/martyrs/src/components/Tree/Tree.vue.cjs +3 -1
- package/dist/martyrs/src/components/Tree/Tree.vue.cjs.map +1 -1
- package/dist/martyrs/src/components/Tree/Tree.vue.js +3 -1
- package/dist/martyrs/src/components/Tree/Tree.vue.js.map +1 -1
- package/dist/martyrs/src/modules/auth/views/components/layouts/Auth.vue.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/components/layouts/Auth.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/EnterPassword.vue.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/EnterPassword.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/Invite.vue.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/Invite.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/ProfileBlogposts.vue.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/ProfileBlogposts.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEdit.vue.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEdit.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/ResetPassword.vue.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/ResetPassword.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/SignIn.vue.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/SignIn.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/SignUp.vue.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/SignUp.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/store/auth.cjs +1 -0
- package/dist/martyrs/src/modules/auth/views/store/auth.cjs.map +1 -1
- package/dist/martyrs/src/modules/auth/views/store/auth.js +1 -0
- package/dist/martyrs/src/modules/auth/views/store/auth.js.map +1 -1
- package/dist/martyrs/src/modules/constructor/components/sections/Constructor.vue.cjs +1 -1
- package/dist/martyrs/src/modules/constructor/components/sections/Constructor.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/pages/EventsBackoffice.vue.cjs +1 -1
- package/dist/martyrs/src/modules/events/components/pages/EventsBackoffice.vue.js +1 -1
- package/dist/martyrs/src/modules/globals/views/classes/globals.store.cjs +107 -21
- package/dist/martyrs/src/modules/globals/views/classes/globals.store.cjs.map +1 -1
- package/dist/martyrs/src/modules/globals/views/classes/globals.store.js +107 -21
- package/dist/martyrs/src/modules/globals/views/classes/globals.store.js.map +1 -1
- package/dist/martyrs/src/modules/globals/views/components/partials/Navigation.vue.cjs +10 -14
- package/dist/martyrs/src/modules/globals/views/components/partials/Navigation.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/globals/views/components/partials/Navigation.vue.js +12 -16
- package/dist/martyrs/src/modules/globals/views/components/partials/Navigation.vue.js.map +1 -1
- package/dist/martyrs/src/modules/globals/views/components/sections/SectionPageTitle.vue.cjs +1 -1
- package/dist/martyrs/src/modules/globals/views/components/sections/SectionPageTitle.vue.js +1 -1
- package/dist/martyrs/src/modules/globals/views/utils/vue-app-renderer.cjs +7 -13
- package/dist/martyrs/src/modules/globals/views/utils/vue-app-renderer.cjs.map +1 -1
- package/dist/martyrs/src/modules/globals/views/utils/vue-app-renderer.js +7 -13
- package/dist/martyrs/src/modules/globals/views/utils/vue-app-renderer.js.map +1 -1
- package/dist/martyrs/src/modules/orders/components/pages/OrderCreate.vue.cjs +6 -7
- package/dist/martyrs/src/modules/orders/components/pages/OrderCreate.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/orders/components/pages/OrderCreate.vue.js +7 -8
- package/dist/martyrs/src/modules/orders/components/pages/OrderCreate.vue.js.map +1 -1
- package/dist/martyrs/src/modules/orders/components/pages/OrderCreateBackoffice.vue.cjs +1 -1
- package/dist/martyrs/src/modules/orders/components/pages/OrderCreateBackoffice.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/pages/Orders.vue.cjs +1 -1
- package/dist/martyrs/src/modules/orders/components/pages/Orders.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/DepartmentEdit.vue.cjs +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/DepartmentEdit.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.cjs +2 -2
- package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.js +2 -2
- package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.cjs +2 -2
- package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.js +2 -2
- package/dist/martyrs/src/modules/organizations/components/pages/OrganizationBackoffice.vue.cjs +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/OrganizationBackoffice.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/OrganizationEdit.vue.cjs +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/OrganizationEdit.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Organizations.vue.cjs +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Organizations.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/Organizations.vue.cjs +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/Organizations.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/blocks/CardCategory.vue.cjs +11 -5
- package/dist/martyrs/src/modules/products/components/blocks/CardCategory.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/products/components/blocks/CardCategory.vue.js +12 -6
- package/dist/martyrs/src/modules/products/components/blocks/CardCategory.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/pages/Categories.vue.cjs +34 -13
- package/dist/martyrs/src/modules/products/components/pages/Categories.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/products/components/pages/Categories.vue.js +35 -14
- package/dist/martyrs/src/modules/products/components/pages/Categories.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.cjs +20 -9
- package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.js +21 -10
- package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/pages/Leftovers.vue.cjs +1 -1
- package/dist/martyrs/src/modules/products/components/pages/Leftovers.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/pages/Product.vue.cjs +1 -1
- package/dist/martyrs/src/modules/products/components/pages/Product.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.cjs +2 -1
- package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.js +2 -1
- package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/pages/Products.vue.cjs +1 -1
- package/dist/martyrs/src/modules/products/components/pages/Products.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/sections/SectionProduct.vue.cjs +1 -1
- package/dist/martyrs/src/modules/products/components/sections/SectionProduct.vue.js +1 -1
- package/dist/martyrs/src/modules/rents/views/components/pages/GanttChart.vue.cjs +1 -1
- package/dist/martyrs/src/modules/rents/views/components/pages/GanttChart.vue.js +1 -1
- package/dist/martyrs/src/modules/rents/views/components/pages/Rents.vue.cjs +1 -1
- package/dist/martyrs/src/modules/rents/views/components/pages/Rents.vue.js +1 -1
- package/dist/martyrs/src/modules/spots/components/pages/SpotEdit.vue.cjs +1 -1
- package/dist/martyrs/src/modules/spots/components/pages/SpotEdit.vue.js +1 -1
- package/dist/martyrs.cjs.js +1 -1
- package/dist/martyrs.css +1 -1
- package/dist/martyrs.es.js +1 -1
- package/dist/notifications.server.js +35 -2
- package/dist/notifications.server.mjs +35 -2
- package/dist/orders.server.js +3 -3
- package/dist/orders.server.mjs +3 -3
- package/dist/organizations.server.js +1 -1
- package/dist/organizations.server.mjs +1 -1
- package/dist/products.server.js +78 -53
- package/dist/products.server.mjs +78 -53
- package/dist/rents.server.js +1 -1
- package/dist/rents.server.mjs +1 -1
- package/dist/style.css +37 -38
- package/dist/wallet.server.js +1 -1
- package/dist/wallet.server.mjs +1 -1
- package/package.json +2 -1
- package/src/components/Feed/Feed.vue +2 -7
- package/src/components/Skeleton/Skeleton.vue +4 -5
- package/src/components/Tree/Tree.vue +5 -2
- package/src/modules/auth/controllers/middlewares/authJwt.js +1 -1
- package/src/modules/auth/views/store/auth.js +2 -1
- package/src/modules/globals/controllers/classes/globals.crud.js +2 -2
- package/src/modules/globals/views/classes/globals.store.js +119 -31
- package/src/modules/globals/views/components/partials/Navigation.vue +11 -10
- package/src/modules/globals/views/utils/vue-app-renderer.js +7 -16
- package/src/modules/icons/entities/IconMusic.vue +14 -0
- package/src/modules/icons/navigation/IconCheck.vue +31 -0
- package/src/modules/icons/navigation/IconHeart.vue +26 -0
- package/src/modules/icons/navigation/IconPause.vue +31 -0
- package/src/modules/icons/navigation/IconPlay.vue +17 -0
- package/src/modules/icons/navigation/IconRefresh.vue +31 -0
- package/src/modules/icons/navigation/IconShuffle.vue +31 -0
- package/src/modules/icons/navigation/IconVolume.vue +31 -0
- package/src/modules/music/components/SidebarMusic.vue +156 -0
- package/src/modules/music/components/cards/AlbumCard.vue +107 -0
- package/src/modules/music/components/cards/ArtistCard.vue +37 -0
- package/src/modules/music/components/cards/PlaylistCard.vue +100 -0
- package/src/modules/music/components/cards/TrackCard.vue +86 -0
- package/src/modules/music/components/forms/PlaylistForm.vue +156 -0
- package/src/modules/music/components/forms/SearchForm.vue +82 -0
- package/src/modules/music/components/forms/UploadForm.vue +313 -0
- package/src/modules/music/components/layouts/MusicLayout.vue +137 -0
- package/src/modules/music/components/lists/AlbumList.vue +25 -0
- package/src/modules/music/components/lists/ArtistList.vue +25 -0
- package/src/modules/music/components/lists/PlaylistList.vue +25 -0
- package/src/modules/music/components/lists/TrackList.vue +175 -0
- package/src/modules/music/components/pages/AlbumDetail.vue +265 -0
- package/src/modules/music/components/pages/ArtistDetail.vue +247 -0
- package/src/modules/music/components/pages/MusicHome.vue +177 -0
- package/src/modules/music/components/pages/MusicLibrary.vue +192 -0
- package/src/modules/music/components/pages/MusicUpload.vue +44 -0
- package/src/modules/music/components/pages/PlaylistDetail.vue +504 -0
- package/src/modules/music/components/pages/SearchResults.vue +397 -0
- package/src/modules/music/components/pages/TrackDetail.vue +143 -0
- package/src/modules/music/components/player/MusicPlayer.vue +202 -0
- package/src/modules/music/components/player/TrackProgress.vue +110 -0
- package/src/modules/music/components/player/VolumeControl.vue +98 -0
- package/src/modules/music/controllers/album.controller.js +98 -0
- package/src/modules/music/controllers/artist.controller.js +111 -0
- package/src/modules/music/controllers/genre.controller.js +71 -0
- package/src/modules/music/controllers/music.controller.js +174 -0
- package/src/modules/music/controllers/playlist.controller.js +182 -0
- package/src/modules/music/controllers/search.controller.js +103 -0
- package/src/modules/music/controllers/stream.controller.js +106 -0
- package/src/modules/music/models/album.model.js +61 -0
- package/src/modules/music/models/artist.model.js +67 -0
- package/src/modules/music/models/genre.model.js +42 -0
- package/src/modules/music/models/play-history.model.js +51 -0
- package/src/modules/music/models/playlist.model.js +69 -0
- package/src/modules/music/models/track.model.js +94 -0
- package/src/modules/music/music.client.js +186 -0
- package/src/modules/music/music.server.js +114 -0
- package/src/modules/music/policies/music.policies.js +84 -0
- package/src/modules/music/router/music.js +77 -0
- package/src/modules/music/routes/album.routes.js +62 -0
- package/src/modules/music/routes/artist.routes.js +67 -0
- package/src/modules/music/routes/genre.routes.js +60 -0
- package/src/modules/music/routes/music.routes.js +145 -0
- package/src/modules/music/routes/playlist.routes.js +99 -0
- package/src/modules/music/routes/search.routes.js +10 -0
- package/src/modules/music/routes/stream.routes.js +38 -0
- package/src/modules/music/store/albums.js +200 -0
- package/src/modules/music/store/artists.js +180 -0
- package/src/modules/music/store/player.js +397 -0
- package/src/modules/music/store/playlists.js +211 -0
- package/src/modules/music/store/search.js +126 -0
- package/src/modules/music/store/tracks.js +230 -0
- package/src/modules/music/websocket/streaming.handler.js +151 -0
- package/src/modules/notifications/controllers/notifications.controller.js +44 -1
- package/src/modules/notifications/notifications.server.js +0 -1
- package/src/modules/notifications/routes/notifications.routes.js +3 -0
- package/src/modules/orders/components/pages/OrderCreate.vue +0 -2
- package/src/modules/products/components/blocks/CardCategory.vue +5 -4
- package/src/modules/products/components/pages/Categories.vue +38 -20
- package/src/modules/products/components/pages/CategoryEdit.vue +16 -7
- package/src/modules/products/components/pages/ProductEdit.vue +1 -0
- package/src/modules/products/controllers/categories.controller.js +155 -103
- package/dist/martyrs/src/components/Menu/Menu.vue.cjs.map +0 -1
- package/dist/martyrs/src/components/Menu/Menu.vue.js.map +0 -1
- package/dist/martyrs/src/components/Tab/Tab.vue2.cjs.map +0 -1
- package/dist/node_modules/.pnpm/@vue_server-renderer@3.5.13_vue@3.5.13_typescript@5.8.3_/node_modules/@vue/server-renderer/dist/server-renderer.esm-bundler.cjs.map +0 -1
- package/dist/node_modules/.pnpm/@vue_server-renderer@3.5.13_vue@3.5.13_typescript@5.8.3_/node_modules/@vue/server-renderer/dist/server-renderer.esm-bundler.js.map +0 -1
- package/dist/node_modules/.pnpm/@vue_shared@3.5.13/node_modules/@vue/shared/dist/shared.esm-bundler.cjs.map +0 -1
- package/dist/node_modules/.pnpm/@vue_shared@3.5.13/node_modules/@vue/shared/dist/shared.esm-bundler.js.map +0 -1
- package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/native.cjs +0 -6
- package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/native.cjs.map +0 -1
- package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/native.js +0 -6
- package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/native.js.map +0 -1
- package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/rng.cjs.map +0 -1
- package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/rng.js +0 -15
- package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/rng.js.map +0 -1
- package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/stringify.cjs +0 -11
- package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/stringify.cjs.map +0 -1
- package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/stringify.js +0 -11
- package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/stringify.js.map +0 -1
- package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/v4.cjs +0 -21
- package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/v4.cjs.map +0 -1
- package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/v4.js +0 -21
- package/dist/node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm-browser/v4.js.map +0 -1
- /package/dist/{node_modules/.pnpm/@vue_shared@3.5.13 → martyrs}/node_modules/@vue/shared/dist/shared.esm-bundler.cjs +0 -0
- /package/dist/{node_modules/.pnpm/@vue_shared@3.5.13 → martyrs}/node_modules/@vue/shared/dist/shared.esm-bundler.js +0 -0
- /package/dist/{node_modules → martyrs/node_modules}/fast-deep-equal/index.cjs +0 -0
- /package/dist/{node_modules → martyrs/node_modules}/fast-deep-equal/index.cjs.map +0 -0
- /package/dist/{node_modules → martyrs/node_modules}/fast-deep-equal/index.js +0 -0
- /package/dist/{node_modules → martyrs/node_modules}/fast-deep-equal/index.js.map +0 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// models/genre.model.js
|
|
2
|
+
module.exports = function(db) {
|
|
3
|
+
const mongoose = db.mongoose;
|
|
4
|
+
const Schema = mongoose.Schema;
|
|
5
|
+
|
|
6
|
+
// Apply common schemas
|
|
7
|
+
const applyCommonSchema = require('@martyrs/src/modules/globals/models/schemas/common.schema.js');
|
|
8
|
+
const applyMetadataSchema = require('@martyrs/src/modules/globals/models/schemas/metadata.schema.js');
|
|
9
|
+
|
|
10
|
+
const GenreSchema = new Schema({
|
|
11
|
+
name: {
|
|
12
|
+
type: String,
|
|
13
|
+
required: true,
|
|
14
|
+
trim: true,
|
|
15
|
+
unique: true
|
|
16
|
+
},
|
|
17
|
+
description: {
|
|
18
|
+
type: String,
|
|
19
|
+
trim: true
|
|
20
|
+
},
|
|
21
|
+
iconUrl: {
|
|
22
|
+
type: String
|
|
23
|
+
},
|
|
24
|
+
popularity: {
|
|
25
|
+
type: Number,
|
|
26
|
+
default: 0
|
|
27
|
+
}
|
|
28
|
+
}, {
|
|
29
|
+
timestamps: true,
|
|
30
|
+
versionKey: false
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Apply common schemas
|
|
34
|
+
applyCommonSchema(GenreSchema, db);
|
|
35
|
+
applyMetadataSchema(GenreSchema, db);
|
|
36
|
+
|
|
37
|
+
// Create indexes
|
|
38
|
+
GenreSchema.index({ name: 'text', description: 'text' });
|
|
39
|
+
GenreSchema.index({ popularity: -1 });
|
|
40
|
+
|
|
41
|
+
return mongoose.models.Genre || mongoose.model('Genre', GenreSchema);
|
|
42
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// models/play-history.model.js
|
|
2
|
+
module.exports = function(db) {
|
|
3
|
+
const mongoose = db.mongoose;
|
|
4
|
+
const Schema = mongoose.Schema;
|
|
5
|
+
|
|
6
|
+
const PlayHistorySchema = new Schema({
|
|
7
|
+
user: {
|
|
8
|
+
type: Schema.Types.ObjectId,
|
|
9
|
+
ref: 'User',
|
|
10
|
+
required: true
|
|
11
|
+
},
|
|
12
|
+
track: {
|
|
13
|
+
type: Schema.Types.ObjectId,
|
|
14
|
+
ref: 'Track',
|
|
15
|
+
required: true
|
|
16
|
+
},
|
|
17
|
+
playedAt: {
|
|
18
|
+
type: Date,
|
|
19
|
+
default: Date.now
|
|
20
|
+
},
|
|
21
|
+
playDuration: {
|
|
22
|
+
type: Number,
|
|
23
|
+
default: 0
|
|
24
|
+
},
|
|
25
|
+
playedFrom: {
|
|
26
|
+
type: String,
|
|
27
|
+
enum: ['playlist', 'album', 'search', 'recommendation', 'artist', 'other'],
|
|
28
|
+
default: 'other'
|
|
29
|
+
},
|
|
30
|
+
contextId: {
|
|
31
|
+
type: Schema.Types.ObjectId,
|
|
32
|
+
refPath: 'playedFrom'
|
|
33
|
+
},
|
|
34
|
+
deviceInfo: {
|
|
35
|
+
type: String
|
|
36
|
+
},
|
|
37
|
+
location: {
|
|
38
|
+
type: String
|
|
39
|
+
}
|
|
40
|
+
}, {
|
|
41
|
+
timestamps: true,
|
|
42
|
+
versionKey: false
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// Create indexes
|
|
46
|
+
PlayHistorySchema.index({ user: 1, playedAt: -1 });
|
|
47
|
+
PlayHistorySchema.index({ track: 1 });
|
|
48
|
+
PlayHistorySchema.index({ playedAt: -1 });
|
|
49
|
+
|
|
50
|
+
return mongoose.models.PlayHistory || mongoose.model('PlayHistory', PlayHistorySchema);
|
|
51
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// models/playlist.model.js
|
|
2
|
+
module.exports = function(db) {
|
|
3
|
+
const mongoose = db.mongoose;
|
|
4
|
+
const Schema = mongoose.Schema;
|
|
5
|
+
|
|
6
|
+
// Apply common schemas
|
|
7
|
+
const applyCommonSchema = require('@martyrs/src/modules/globals/models/schemas/common.schema.js');
|
|
8
|
+
const applyMetadataSchema = require('@martyrs/src/modules/globals/models/schemas/metadata.schema.js');
|
|
9
|
+
const applyOwnershipSchema = require('@martyrs/src/modules/globals/models/schemas/ownership.schema.js');
|
|
10
|
+
const applyEngagementSchema = require('@martyrs/src/modules/globals/models/schemas/engagement.schema.js');
|
|
11
|
+
|
|
12
|
+
const PlaylistSchema = new Schema({
|
|
13
|
+
title: {
|
|
14
|
+
type: String,
|
|
15
|
+
required: true,
|
|
16
|
+
trim: true
|
|
17
|
+
},
|
|
18
|
+
description: {
|
|
19
|
+
type: String,
|
|
20
|
+
trim: true
|
|
21
|
+
},
|
|
22
|
+
coverUrl: {
|
|
23
|
+
type: String
|
|
24
|
+
},
|
|
25
|
+
tracks: [{
|
|
26
|
+
track: {
|
|
27
|
+
type: Schema.Types.ObjectId,
|
|
28
|
+
ref: 'Track'
|
|
29
|
+
},
|
|
30
|
+
addedAt: {
|
|
31
|
+
type: Date,
|
|
32
|
+
default: Date.now
|
|
33
|
+
}
|
|
34
|
+
}],
|
|
35
|
+
isPublic: {
|
|
36
|
+
type: Boolean,
|
|
37
|
+
default: true
|
|
38
|
+
},
|
|
39
|
+
followers: {
|
|
40
|
+
type: Number,
|
|
41
|
+
default: 0
|
|
42
|
+
},
|
|
43
|
+
isCollaborative: {
|
|
44
|
+
type: Boolean,
|
|
45
|
+
default: false
|
|
46
|
+
},
|
|
47
|
+
collaborators: [{
|
|
48
|
+
type: Schema.Types.ObjectId,
|
|
49
|
+
ref: 'User'
|
|
50
|
+
}]
|
|
51
|
+
}, {
|
|
52
|
+
timestamps: true,
|
|
53
|
+
versionKey: false
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// Apply common schemas
|
|
57
|
+
applyCommonSchema(PlaylistSchema, db);
|
|
58
|
+
applyMetadataSchema(PlaylistSchema, db);
|
|
59
|
+
applyOwnershipSchema(PlaylistSchema, db);
|
|
60
|
+
applyEngagementSchema(PlaylistSchema, db);
|
|
61
|
+
|
|
62
|
+
// Create indexes
|
|
63
|
+
PlaylistSchema.index({ title: 'text', description: 'text' });
|
|
64
|
+
PlaylistSchema.index({ isPublic: 1 });
|
|
65
|
+
PlaylistSchema.index({ followers: -1 });
|
|
66
|
+
PlaylistSchema.index({ 'tracks.addedAt': -1 });
|
|
67
|
+
|
|
68
|
+
return mongoose.models.Playlist || mongoose.model('Playlist', PlaylistSchema);
|
|
69
|
+
};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// models/track.model.js
|
|
2
|
+
module.exports = function(db) {
|
|
3
|
+
const mongoose = db.mongoose;
|
|
4
|
+
const Schema = mongoose.Schema;
|
|
5
|
+
|
|
6
|
+
// Apply common schemas
|
|
7
|
+
const applyCommonSchema = require('@martyrs/src/modules/globals/models/schemas/common.schema.js');
|
|
8
|
+
const applyMetadataSchema = require('@martyrs/src/modules/globals/models/schemas/metadata.schema.js');
|
|
9
|
+
const applyOwnershipSchema = require('@martyrs/src/modules/globals/models/schemas/ownership.schema.js');
|
|
10
|
+
const applyEngagementSchema = require('@martyrs/src/modules/globals/models/schemas/engagement.schema.js');
|
|
11
|
+
|
|
12
|
+
const TrackSchema = new Schema({
|
|
13
|
+
title: {
|
|
14
|
+
type: String,
|
|
15
|
+
required: true,
|
|
16
|
+
trim: true
|
|
17
|
+
},
|
|
18
|
+
artist: {
|
|
19
|
+
type: Schema.Types.ObjectId,
|
|
20
|
+
ref: 'Artist',
|
|
21
|
+
required: true
|
|
22
|
+
},
|
|
23
|
+
album: {
|
|
24
|
+
type: Schema.Types.ObjectId,
|
|
25
|
+
ref: 'Album'
|
|
26
|
+
},
|
|
27
|
+
duration: {
|
|
28
|
+
type: Number,
|
|
29
|
+
default: 0
|
|
30
|
+
},
|
|
31
|
+
fileUrl: {
|
|
32
|
+
type: String,
|
|
33
|
+
required: true
|
|
34
|
+
},
|
|
35
|
+
coverUrl: {
|
|
36
|
+
type: String
|
|
37
|
+
},
|
|
38
|
+
genre: [{
|
|
39
|
+
type: Schema.Types.ObjectId,
|
|
40
|
+
ref: 'Genre'
|
|
41
|
+
}],
|
|
42
|
+
releaseDate: {
|
|
43
|
+
type: Date,
|
|
44
|
+
default: Date.now
|
|
45
|
+
},
|
|
46
|
+
isExplicit: {
|
|
47
|
+
type: Boolean,
|
|
48
|
+
default: false
|
|
49
|
+
},
|
|
50
|
+
lyrics: {
|
|
51
|
+
type: String
|
|
52
|
+
},
|
|
53
|
+
playCount: {
|
|
54
|
+
type: Number,
|
|
55
|
+
default: 0
|
|
56
|
+
},
|
|
57
|
+
isPublic: {
|
|
58
|
+
type: Boolean,
|
|
59
|
+
default: true
|
|
60
|
+
}
|
|
61
|
+
}, {
|
|
62
|
+
timestamps: true,
|
|
63
|
+
versionKey: false
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// Apply common schemas
|
|
67
|
+
applyCommonSchema(TrackSchema, db);
|
|
68
|
+
applyMetadataSchema(TrackSchema, db);
|
|
69
|
+
applyOwnershipSchema(TrackSchema, db);
|
|
70
|
+
applyEngagementSchema(TrackSchema, db);
|
|
71
|
+
|
|
72
|
+
// Create indexes for efficient querying
|
|
73
|
+
TrackSchema.index({ title: 'text' });
|
|
74
|
+
TrackSchema.index({ artist: 1 });
|
|
75
|
+
TrackSchema.index({ album: 1 });
|
|
76
|
+
TrackSchema.index({ releaseDate: -1 });
|
|
77
|
+
TrackSchema.index({ playCount: -1 });
|
|
78
|
+
|
|
79
|
+
// Pre-save middleware to create a URL if not provided
|
|
80
|
+
TrackSchema.pre('save', function(next) {
|
|
81
|
+
if (!this.url) {
|
|
82
|
+
const createFriendlyURL = require('@martyrs/src/modules/globals/controllers/utils/seo-friendly-url');
|
|
83
|
+
this.url = createFriendlyURL(`${this.title}-${this._id}`);
|
|
84
|
+
}
|
|
85
|
+
next();
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// Virtual for artist name (useful for APIs)
|
|
89
|
+
TrackSchema.virtual('artistName').get(function() {
|
|
90
|
+
return this.artist ? this.artist.name : '';
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
return mongoose.models.Track || mongoose.model('Track', TrackSchema);
|
|
94
|
+
};
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
// Store modules
|
|
2
|
+
import * as storeTracks from './store/tracks.js';
|
|
3
|
+
import * as storePlaylists from './store/playlists.js';
|
|
4
|
+
import * as storeAlbums from './store/albums.js';
|
|
5
|
+
import * as storeArtists from './store/artists.js';
|
|
6
|
+
import * as storePlayer from './store/player.js';
|
|
7
|
+
import * as storeSearch from './store/search.js';
|
|
8
|
+
|
|
9
|
+
// Router
|
|
10
|
+
import routerMusic from './router/music';
|
|
11
|
+
|
|
12
|
+
// Layouts
|
|
13
|
+
import MusicLayout from './components/layouts/MusicLayout.vue';
|
|
14
|
+
|
|
15
|
+
// Pages
|
|
16
|
+
import MusicHome from './components/pages/MusicHome.vue';
|
|
17
|
+
import SearchResults from './components/pages/SearchResults.vue';
|
|
18
|
+
import ArtistDetail from './components/pages/ArtistDetail.vue';
|
|
19
|
+
import AlbumDetail from './components/pages/AlbumDetail.vue';
|
|
20
|
+
import PlaylistDetail from './components/pages/PlaylistDetail.vue';
|
|
21
|
+
import TrackDetail from './components/pages/TrackDetail.vue';
|
|
22
|
+
import MusicLibrary from './components/pages/MusicLibrary.vue';
|
|
23
|
+
import MusicUpload from './components/pages/MusicUpload.vue';
|
|
24
|
+
|
|
25
|
+
// Components - Player
|
|
26
|
+
import MusicPlayer from './components/player/MusicPlayer.vue';
|
|
27
|
+
import TrackProgress from './components/player/TrackProgress.vue';
|
|
28
|
+
import VolumeControl from './components/player/VolumeControl.vue';
|
|
29
|
+
|
|
30
|
+
// Components - Cards
|
|
31
|
+
import TrackCard from './components/cards/TrackCard.vue';
|
|
32
|
+
import AlbumCard from './components/cards/AlbumCard.vue';
|
|
33
|
+
import PlaylistCard from './components/cards/PlaylistCard.vue';
|
|
34
|
+
import ArtistCard from './components/cards/ArtistCard.vue';
|
|
35
|
+
|
|
36
|
+
// Components - Lists
|
|
37
|
+
import TrackList from './components/lists/TrackList.vue';
|
|
38
|
+
import AlbumList from './components/lists/AlbumList.vue';
|
|
39
|
+
import PlaylistList from './components/lists/PlaylistList.vue';
|
|
40
|
+
import ArtistList from './components/lists/ArtistList.vue';
|
|
41
|
+
|
|
42
|
+
// Components - Forms
|
|
43
|
+
import PlaylistForm from './components/forms/PlaylistForm.vue';
|
|
44
|
+
import SearchForm from './components/forms/SearchForm.vue';
|
|
45
|
+
import UploadForm from './components/forms/UploadForm.vue';
|
|
46
|
+
|
|
47
|
+
// WebSocket integration for streaming
|
|
48
|
+
import globalWebSocket from '@martyrs/src/modules/globals/views/classes/globals.websocket.js';
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Initialize Music module on client-side
|
|
52
|
+
* @param {Object} app - Vue app instance
|
|
53
|
+
* @param {Object} store - Global store instance
|
|
54
|
+
* @param {Object} router - Vue router instance
|
|
55
|
+
* @param {Object} config - Configuration options
|
|
56
|
+
* @param {Object} options - Additional options
|
|
57
|
+
*/
|
|
58
|
+
function initializeMusic(app, store, router, config, options = {}) {
|
|
59
|
+
const route = options.route || 'Home';
|
|
60
|
+
|
|
61
|
+
// Register routes
|
|
62
|
+
router.addRoute(route, routerMusic);
|
|
63
|
+
|
|
64
|
+
// Register store modules
|
|
65
|
+
store.addStore('tracks', storeTracks);
|
|
66
|
+
store.addStore('playlists', storePlaylists);
|
|
67
|
+
store.addStore('albums', storeAlbums);
|
|
68
|
+
store.addStore('artists', storeArtists);
|
|
69
|
+
store.addStore('player', storePlayer);
|
|
70
|
+
store.addStore('search', storeSearch);
|
|
71
|
+
|
|
72
|
+
// Set up WebSocket subscription for music streaming
|
|
73
|
+
if (options.enableStreaming !== false && app.config.globalProperties.WSS_URL) {
|
|
74
|
+
globalWebSocket.initialize({
|
|
75
|
+
wsUrl: app.config.globalProperties.WSS_URL,
|
|
76
|
+
maxReconnectAttempts: 10,
|
|
77
|
+
reconnectDelay: 2000
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// Subscribe to music streaming module when authenticated
|
|
81
|
+
if (options.userId) {
|
|
82
|
+
globalWebSocket.connect(options.userId).then(() => {
|
|
83
|
+
globalWebSocket.subscribeModule('music-streaming');
|
|
84
|
+
}).catch(err => {
|
|
85
|
+
console.error('Failed to connect to WebSocket for music streaming:', err);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Register global components if needed
|
|
91
|
+
app.component('MusicPlayer', MusicPlayer);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Module export
|
|
95
|
+
const ModuleMusic = {
|
|
96
|
+
initialize: initializeMusic,
|
|
97
|
+
views: {
|
|
98
|
+
store: {
|
|
99
|
+
storeTracks,
|
|
100
|
+
storePlaylists,
|
|
101
|
+
storeAlbums,
|
|
102
|
+
storeArtists,
|
|
103
|
+
storePlayer,
|
|
104
|
+
storeSearch
|
|
105
|
+
},
|
|
106
|
+
router: {
|
|
107
|
+
routerMusic
|
|
108
|
+
},
|
|
109
|
+
components: {
|
|
110
|
+
// Layouts
|
|
111
|
+
MusicLayout,
|
|
112
|
+
// Pages
|
|
113
|
+
MusicHome,
|
|
114
|
+
SearchResults,
|
|
115
|
+
ArtistDetail,
|
|
116
|
+
AlbumDetail,
|
|
117
|
+
PlaylistDetail,
|
|
118
|
+
TrackDetail,
|
|
119
|
+
MusicLibrary,
|
|
120
|
+
MusicUpload,
|
|
121
|
+
// Player Components
|
|
122
|
+
MusicPlayer,
|
|
123
|
+
TrackProgress,
|
|
124
|
+
VolumeControl,
|
|
125
|
+
// Cards
|
|
126
|
+
TrackCard,
|
|
127
|
+
AlbumCard,
|
|
128
|
+
PlaylistCard,
|
|
129
|
+
ArtistCard,
|
|
130
|
+
// Lists
|
|
131
|
+
TrackList,
|
|
132
|
+
AlbumList,
|
|
133
|
+
PlaylistList,
|
|
134
|
+
ArtistList,
|
|
135
|
+
// Forms
|
|
136
|
+
PlaylistForm,
|
|
137
|
+
SearchForm,
|
|
138
|
+
UploadForm,
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
// Named exports for direct component imports
|
|
144
|
+
export {
|
|
145
|
+
// Layout
|
|
146
|
+
MusicLayout,
|
|
147
|
+
// Pages
|
|
148
|
+
MusicHome,
|
|
149
|
+
SearchResults,
|
|
150
|
+
ArtistDetail,
|
|
151
|
+
AlbumDetail,
|
|
152
|
+
PlaylistDetail,
|
|
153
|
+
TrackDetail,
|
|
154
|
+
MusicLibrary,
|
|
155
|
+
MusicUpload,
|
|
156
|
+
// Player Components
|
|
157
|
+
MusicPlayer,
|
|
158
|
+
TrackProgress,
|
|
159
|
+
VolumeControl,
|
|
160
|
+
// Cards
|
|
161
|
+
TrackCard,
|
|
162
|
+
AlbumCard,
|
|
163
|
+
PlaylistCard,
|
|
164
|
+
ArtistCard,
|
|
165
|
+
// Lists
|
|
166
|
+
TrackList,
|
|
167
|
+
AlbumList,
|
|
168
|
+
PlaylistList,
|
|
169
|
+
ArtistList,
|
|
170
|
+
// Forms
|
|
171
|
+
PlaylistForm,
|
|
172
|
+
SearchForm,
|
|
173
|
+
UploadForm,
|
|
174
|
+
// Store modules
|
|
175
|
+
storeTracks,
|
|
176
|
+
storePlaylists,
|
|
177
|
+
storeAlbums,
|
|
178
|
+
storeArtists,
|
|
179
|
+
storePlayer,
|
|
180
|
+
storeSearch,
|
|
181
|
+
// Router
|
|
182
|
+
routerMusic
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
// Default export
|
|
186
|
+
export default ModuleMusic;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// music.server.js (update)
|
|
2
|
+
const MusicController = require('./controllers/music.controller.js');
|
|
3
|
+
const PlaylistController = require('./controllers/playlist.controller.js');
|
|
4
|
+
const AlbumController = require('./controllers/album.controller.js');
|
|
5
|
+
const ArtistController = require('./controllers/artist.controller.js');
|
|
6
|
+
const StreamController = require('./controllers/stream.controller.js');
|
|
7
|
+
const SearchController = require('./controllers/search.controller.js');
|
|
8
|
+
const GenreController = require('./controllers/genre.controller.js');
|
|
9
|
+
|
|
10
|
+
// Import routes
|
|
11
|
+
const musicRoutes = require('./routes/music.routes.js');
|
|
12
|
+
const playlistRoutes = require('./routes/playlist.routes.js');
|
|
13
|
+
const albumRoutes = require('./routes/album.routes.js');
|
|
14
|
+
const artistRoutes = require('./routes/artist.routes.js');
|
|
15
|
+
const streamRoutes = require('./routes/stream.routes.js');
|
|
16
|
+
const searchRoutes = require('./routes/search.routes.js');
|
|
17
|
+
const genreRoutes = require('./routes/genre.routes.js');
|
|
18
|
+
|
|
19
|
+
// Import models
|
|
20
|
+
const TrackModel = require('./models/track.model.js');
|
|
21
|
+
const PlaylistModel = require('./models/playlist.model.js');
|
|
22
|
+
const AlbumModel = require('./models/album.model.js');
|
|
23
|
+
const ArtistModel = require('./models/artist.model.js');
|
|
24
|
+
const GenreModel = require('./models/genre.model.js');
|
|
25
|
+
const PlayHistoryModel = require('./models/play-history.model.js');
|
|
26
|
+
|
|
27
|
+
// Import WebSocket handlers
|
|
28
|
+
const StreamingHandler = require('./websocket/streaming.handler.js');
|
|
29
|
+
|
|
30
|
+
// Import ABAC policies
|
|
31
|
+
const musicPolicies = require('./policies/music.policies.js');
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Initialize the Music module
|
|
35
|
+
* @param {Object} app - Express application instance
|
|
36
|
+
* @param {Object} db - Database connection object
|
|
37
|
+
* @param {Array} origins - CORS allowed origins
|
|
38
|
+
* @param {String} publicPath - Path to public files
|
|
39
|
+
*/
|
|
40
|
+
function initializeMusic({app, db, wss, origins, publicPath}) {
|
|
41
|
+
// Register models in the database object
|
|
42
|
+
db.track = TrackModel(db);
|
|
43
|
+
db.playlist = PlaylistModel(db);
|
|
44
|
+
db.album = AlbumModel(db);
|
|
45
|
+
db.artist = ArtistModel(db);
|
|
46
|
+
db.genre = GenreModel(db);
|
|
47
|
+
db.playHistory = PlayHistoryModel(db);
|
|
48
|
+
|
|
49
|
+
console.log('server publioc is', publicPath)
|
|
50
|
+
|
|
51
|
+
// Set up routes if app is provided
|
|
52
|
+
if (app) {
|
|
53
|
+
musicRoutes(app, db, origins, publicPath);
|
|
54
|
+
playlistRoutes(app, db, origins, publicPath);
|
|
55
|
+
albumRoutes(app, db, origins, publicPath);
|
|
56
|
+
artistRoutes(app, db, origins, publicPath);
|
|
57
|
+
streamRoutes(app, db, origins, publicPath);
|
|
58
|
+
searchRoutes(app, db, origins, publicPath);
|
|
59
|
+
genreRoutes(app, db, origins, publicPath);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Initialize ABAC policies for music module
|
|
63
|
+
const { getInstance } = require('@martyrs/src/modules/globals/controllers/classes/globals.abac.js');
|
|
64
|
+
const abac = getInstance(db);
|
|
65
|
+
musicPolicies(abac);
|
|
66
|
+
|
|
67
|
+
// Set up WebSocket handlers if WebSocketManager is available
|
|
68
|
+
const { WebSocketManager } = require('@martyrs/src/modules/globals/controllers/classes/globals.websocket.js');
|
|
69
|
+
if (global.webSocketManager && global.webSocketManager instanceof WebSocketManager) {
|
|
70
|
+
global.webSocketManager.registerModule('music-streaming', StreamingHandler(db).handleStreamingMessage);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Initialize cache for frequently accessed data
|
|
74
|
+
const Cache = require('@martyrs/src/modules/globals/controllers/classes/globals.cache');
|
|
75
|
+
const musicCache = new Cache({ ttlSeconds: 60 * 15 }); // 15 minute cache
|
|
76
|
+
|
|
77
|
+
// Initialize logger for music-specific logs
|
|
78
|
+
const Logger = require('@martyrs/src/modules/globals/controllers/classes/globals.logger');
|
|
79
|
+
const musicLogger = new Logger(db);
|
|
80
|
+
|
|
81
|
+
// Log module initialization
|
|
82
|
+
musicLogger.info('Music module initialized');
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Export initialization function, controllers, routes, and models
|
|
86
|
+
module.exports = {
|
|
87
|
+
initialize: initializeMusic,
|
|
88
|
+
models: {
|
|
89
|
+
TrackModel,
|
|
90
|
+
PlaylistModel,
|
|
91
|
+
AlbumModel,
|
|
92
|
+
ArtistModel,
|
|
93
|
+
GenreModel,
|
|
94
|
+
PlayHistoryModel
|
|
95
|
+
},
|
|
96
|
+
routes: {
|
|
97
|
+
musicRoutes,
|
|
98
|
+
playlistRoutes,
|
|
99
|
+
albumRoutes,
|
|
100
|
+
artistRoutes,
|
|
101
|
+
streamRoutes,
|
|
102
|
+
searchRoutes,
|
|
103
|
+
genreRoutes
|
|
104
|
+
},
|
|
105
|
+
controllers: {
|
|
106
|
+
MusicController,
|
|
107
|
+
PlaylistController,
|
|
108
|
+
AlbumController,
|
|
109
|
+
ArtistController,
|
|
110
|
+
StreamController,
|
|
111
|
+
SearchController,
|
|
112
|
+
GenreController
|
|
113
|
+
}
|
|
114
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// policies/music.policies.js
|
|
2
|
+
module.exports = function initializeMusicPolicies(abacAccessControl) {
|
|
3
|
+
// Policy for handling music resource ownership
|
|
4
|
+
abacAccessControl.registerResourcePolicy('tracks', async (context) => {
|
|
5
|
+
const { user, action, currentResource, resourceModel } = context;
|
|
6
|
+
const ObjectId = abacAccessControl.db.mongoose.Types.ObjectId;
|
|
7
|
+
|
|
8
|
+
// Allow public read access for published tracks
|
|
9
|
+
if (action === 'read' && currentResource?.status === 'published' && currentResource?.isPublic === true) {
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// For create actions, verify ownership
|
|
14
|
+
if (action === 'create') {
|
|
15
|
+
// Ensure that creator.target matches the authenticated user
|
|
16
|
+
if (context.data.creator && context.data.creator.target) {
|
|
17
|
+
return context.data.creator.target.toString() === user.toString();
|
|
18
|
+
}
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// For update and delete, verify ownership
|
|
23
|
+
if (['update', 'edit', 'delete'].includes(action) && currentResource) {
|
|
24
|
+
// If the resource has an organization owner, check if user belongs to that organization
|
|
25
|
+
if (currentResource.owner && currentResource.owner.type === 'Organization') {
|
|
26
|
+
// Here you would typically check if the user is part of the organization
|
|
27
|
+
// This would require a query to the organization's members
|
|
28
|
+
const Organization = abacAccessControl.db.organization;
|
|
29
|
+
const org = await Organization.findOne({
|
|
30
|
+
_id: currentResource.owner.target,
|
|
31
|
+
members: { $elemMatch: { user: new ObjectId(user) } }
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
if (org) return true;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Check if the user is the creator
|
|
38
|
+
if (currentResource.creator &&
|
|
39
|
+
currentResource.creator.target &&
|
|
40
|
+
currentResource.creator.target.toString() === user.toString()) {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Default access denied
|
|
48
|
+
return false;
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
// Apply the same policies to albums
|
|
52
|
+
abacAccessControl.registerResourcePolicy('albums', async (context) => {
|
|
53
|
+
// Reuse the track policy logic
|
|
54
|
+
return abacAccessControl.policies.resources.tracks(context);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// Apply the same policies to playlists
|
|
58
|
+
abacAccessControl.registerResourcePolicy('playlists', async (context) => {
|
|
59
|
+
const { user, action, currentResource } = context;
|
|
60
|
+
|
|
61
|
+
// Special case for collaborative playlists
|
|
62
|
+
if (currentResource && currentResource.isCollaborative &&
|
|
63
|
+
currentResource.collaborators &&
|
|
64
|
+
currentResource.collaborators.some(collaborator =>
|
|
65
|
+
collaborator.toString() === user.toString()
|
|
66
|
+
)) {
|
|
67
|
+
// Collaborators can edit but not delete
|
|
68
|
+
if (action === 'edit' || action === 'update') {
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// For other cases, reuse the track policy logic
|
|
74
|
+
return abacAccessControl.policies.resources.tracks(context);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// Apply the same policies to artists
|
|
78
|
+
abacAccessControl.registerResourcePolicy('artists', async (context) => {
|
|
79
|
+
// Reuse the track policy logic
|
|
80
|
+
return abacAccessControl.policies.resources.tracks(context);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
return abacAccessControl;
|
|
84
|
+
};
|