@burdenoff/microfe-hookmovies 2026.706.1 → 2026.706.3

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 (55) hide show
  1. package/dist/hookmovies/HookMoviesRoutes.js +74 -6
  2. package/dist/hookmovies/HookMoviesRoutes.js.map +1 -1
  3. package/dist/hookmovies/components/index.js +7 -0
  4. package/dist/hookmovies/context/HookMoviesContext.js +64 -40
  5. package/dist/hookmovies/context/HookMoviesContext.js.map +1 -1
  6. package/dist/hookmovies/hooks/useFiles.js +54 -23
  7. package/dist/hookmovies/hooks/useFiles.js.map +1 -1
  8. package/dist/hookmovies/hooks/useHookMoviesApi.js +646 -122
  9. package/dist/hookmovies/hooks/useHookMoviesApi.js.map +1 -1
  10. package/dist/hookmovies/pages/ai/ConciergePage.js +330 -0
  11. package/dist/hookmovies/pages/ai/ConciergePage.js.map +1 -0
  12. package/dist/hookmovies/pages/analytics/AnalyticsPage.js +450 -0
  13. package/dist/hookmovies/pages/analytics/AnalyticsPage.js.map +1 -0
  14. package/dist/hookmovies/pages/analytics/PayoutsPage.js +499 -0
  15. package/dist/hookmovies/pages/analytics/PayoutsPage.js.map +1 -0
  16. package/dist/hookmovies/pages/auditions/AuditionsPage.js +3 -3
  17. package/dist/hookmovies/pages/catalog/PeoplePage.js +3 -3
  18. package/dist/hookmovies/pages/catalog/StudiosPage.js +3 -3
  19. package/dist/hookmovies/pages/catalog/TitleDetailPage.js +852 -454
  20. package/dist/hookmovies/pages/catalog/TitleDetailPage.js.map +1 -1
  21. package/dist/hookmovies/pages/catalog/TitlesPage.js +4 -4
  22. package/dist/hookmovies/pages/commerce/CheckoutPage.js +430 -0
  23. package/dist/hookmovies/pages/commerce/CheckoutPage.js.map +1 -0
  24. package/dist/hookmovies/pages/consumer/DiscoveryPage.js +422 -0
  25. package/dist/hookmovies/pages/consumer/DiscoveryPage.js.map +1 -0
  26. package/dist/hookmovies/pages/consumer/HooksPage.js +252 -0
  27. package/dist/hookmovies/pages/consumer/HooksPage.js.map +1 -0
  28. package/dist/hookmovies/pages/consumer/PlayerPage.js +542 -0
  29. package/dist/hookmovies/pages/consumer/PlayerPage.js.map +1 -0
  30. package/dist/hookmovies/pages/consumer/TitleViewPage.js +424 -0
  31. package/dist/hookmovies/pages/consumer/TitleViewPage.js.map +1 -0
  32. package/dist/hookmovies/pages/developer/DevPortalPage.js +815 -0
  33. package/dist/hookmovies/pages/developer/DevPortalPage.js.map +1 -0
  34. package/dist/hookmovies/pages/distribution/RightsWindowsPage.js +3 -3
  35. package/dist/hookmovies/pages/engagement/ReviewsPage.js +201 -143
  36. package/dist/hookmovies/pages/engagement/ReviewsPage.js.map +1 -1
  37. package/dist/hookmovies/pages/library/EntitlementsPage.js +3 -3
  38. package/dist/hookmovies/pages/library/EntitlementsPage.js.map +1 -1
  39. package/dist/hookmovies/pages/library/ListsPage.js +3 -3
  40. package/dist/hookmovies/pages/live/LivePage.js +608 -0
  41. package/dist/hookmovies/pages/live/LivePage.js.map +1 -0
  42. package/dist/hookmovies/pages/localization/LocalizationPage.js +656 -0
  43. package/dist/hookmovies/pages/localization/LocalizationPage.js.map +1 -0
  44. package/dist/hookmovies/pages/onboarding/OnboardingPage.js +366 -0
  45. package/dist/hookmovies/pages/onboarding/OnboardingPage.js.map +1 -0
  46. package/dist/hookmovies/pages/productions/ProductionsPage.js +3 -3
  47. package/dist/hookmovies/pages/social/ProfilesPage.js +701 -0
  48. package/dist/hookmovies/pages/social/ProfilesPage.js.map +1 -0
  49. package/dist/hookmovies/pages/social/WatchPartyListPage.js +281 -0
  50. package/dist/hookmovies/pages/social/WatchPartyListPage.js.map +1 -0
  51. package/dist/hookmovies/pages/social/WatchPartyRoomPage.js +567 -0
  52. package/dist/hookmovies/pages/social/WatchPartyRoomPage.js.map +1 -0
  53. package/dist/hookmovies/pages/trust/ModerationPage.js +320 -0
  54. package/dist/hookmovies/pages/trust/ModerationPage.js.map +1 -0
  55. package/package.json +1 -1
@@ -4,15 +4,15 @@ import { Suspense as n, lazy as r } from "react";
4
4
  import { Navigate as i, Route as a, Routes as o, useLocation as s } from "react-router-dom";
5
5
  import { jsx as c, jsxs as l } from "react/jsx-runtime";
6
6
  //#region src/hookmovies/HookMoviesRoutes.tsx
7
- var u = r(() => import("./pages/catalog/TitlesPage.js").then((e) => ({ default: e.TitlesPage }))), d = r(() => import("./pages/catalog/TitleCreatePage.js").then((e) => ({ default: e.TitleCreatePage }))), f = r(() => import("./pages/catalog/TitleDetailPage.js").then((e) => ({ default: e.TitleDetailPage }))), p = r(() => import("./pages/catalog/StudiosPage.js").then((e) => ({ default: e.StudiosPage }))), m = r(() => import("./pages/catalog/PeoplePage.js").then((e) => ({ default: e.PeoplePage }))), h = r(() => import("./pages/productions/ProductionsPage.js").then((e) => ({ default: e.ProductionsPage }))), g = r(() => import("./pages/productions/ProductionCreatePage.js").then((e) => ({ default: e.ProductionCreatePage }))), _ = r(() => import("./pages/productions/ProductionDetailPage.js").then((e) => ({ default: e.ProductionDetailPage }))), v = r(() => import("./pages/auditions/AuditionsPage.js").then((e) => ({ default: e.AuditionsPage }))), y = r(() => import("./pages/auditions/AuditionCreatePage.js").then((e) => ({ default: e.AuditionCreatePage }))), b = r(() => import("./pages/auditions/AuditionDetailPage.js").then((e) => ({ default: e.AuditionDetailPage }))), x = r(() => import("./pages/engagement/ReviewsPage.js").then((e) => ({ default: e.ReviewsPage }))), S = r(() => import("./pages/distribution/RightsWindowsPage.js").then((e) => ({ default: e.RightsWindowsPage }))), C = r(() => import("./pages/library/ListsPage.js").then((e) => ({ default: e.ListsPage }))), w = r(() => import("./pages/library/EntitlementsPage.js").then((e) => ({ default: e.EntitlementsPage }))), T = () => /* @__PURE__ */ c("div", {
7
+ var u = r(() => import("./pages/catalog/TitlesPage.js").then((e) => ({ default: e.TitlesPage }))), d = r(() => import("./pages/catalog/TitleCreatePage.js").then((e) => ({ default: e.TitleCreatePage }))), f = r(() => import("./pages/catalog/TitleDetailPage.js").then((e) => ({ default: e.TitleDetailPage }))), p = r(() => import("./pages/catalog/StudiosPage.js").then((e) => ({ default: e.StudiosPage }))), m = r(() => import("./pages/catalog/PeoplePage.js").then((e) => ({ default: e.PeoplePage }))), h = r(() => import("./pages/productions/ProductionsPage.js").then((e) => ({ default: e.ProductionsPage }))), g = r(() => import("./pages/productions/ProductionCreatePage.js").then((e) => ({ default: e.ProductionCreatePage }))), _ = r(() => import("./pages/productions/ProductionDetailPage.js").then((e) => ({ default: e.ProductionDetailPage }))), v = r(() => import("./pages/auditions/AuditionsPage.js").then((e) => ({ default: e.AuditionsPage }))), y = r(() => import("./pages/auditions/AuditionCreatePage.js").then((e) => ({ default: e.AuditionCreatePage }))), b = r(() => import("./pages/auditions/AuditionDetailPage.js").then((e) => ({ default: e.AuditionDetailPage }))), x = r(() => import("./pages/engagement/ReviewsPage.js").then((e) => ({ default: e.ReviewsPage }))), S = r(() => import("./pages/distribution/RightsWindowsPage.js").then((e) => ({ default: e.RightsWindowsPage }))), C = r(() => import("./pages/library/ListsPage.js").then((e) => ({ default: e.ListsPage }))), w = r(() => import("./pages/library/EntitlementsPage.js").then((e) => ({ default: e.EntitlementsPage }))), T = r(() => import("./pages/consumer/DiscoveryPage.js").then((e) => ({ default: e.DiscoveryPage }))), E = r(() => import("./pages/consumer/TitleViewPage.js").then((e) => ({ default: e.TitleViewPage }))), D = r(() => import("./pages/consumer/PlayerPage.js").then((e) => ({ default: e.PlayerPage }))), O = r(() => import("./pages/consumer/HooksPage.js").then((e) => ({ default: e.HooksPage }))), k = r(() => import("./pages/social/ProfilesPage.js").then((e) => ({ default: e.ProfilesPage }))), A = r(() => import("./pages/social/WatchPartyListPage.js").then((e) => ({ default: e.WatchPartyListPage }))), j = r(() => import("./pages/social/WatchPartyRoomPage.js").then((e) => ({ default: e.WatchPartyRoomPage }))), M = r(() => import("./pages/commerce/CheckoutPage.js").then((e) => ({ default: e.CheckoutPage }))), N = r(() => import("./pages/analytics/PayoutsPage.js").then((e) => ({ default: e.PayoutsPage }))), P = r(() => import("./pages/analytics/AnalyticsPage.js").then((e) => ({ default: e.AnalyticsPage }))), F = r(() => import("./pages/trust/ModerationPage.js").then((e) => ({ default: e.ModerationPage }))), I = r(() => import("./pages/onboarding/OnboardingPage.js").then((e) => ({ default: e.OnboardingPage }))), L = r(() => import("./pages/developer/DevPortalPage.js").then((e) => ({ default: e.DevPortalPage }))), R = r(() => import("./pages/live/LivePage.js").then((e) => ({ default: e.LivePage }))), z = r(() => import("./pages/localization/LocalizationPage.js").then((e) => ({ default: e.LocalizationPage }))), B = r(() => import("./pages/ai/ConciergePage.js").then((e) => ({ default: e.ConciergePage }))), V = () => /* @__PURE__ */ c("div", {
8
8
  className: "flex min-h-[400px] items-center justify-center",
9
9
  children: /* @__PURE__ */ c("div", { className: "h-8 w-8 animate-spin rounded-full border-b-2 border-action-primary-bg" })
10
- }), E = () => {
11
- let { basePath: r, isStandalone: E } = e(), D = s(), O = r === "/" ? "" : (r ?? "").replace(/\/$/, "");
12
- return O && !E && !(D.pathname === O || D.pathname.startsWith(O + "/")) ? null : /* @__PURE__ */ c("div", {
10
+ }), H = () => {
11
+ let { basePath: r, isStandalone: H } = e(), U = s(), W = r === "/" ? "" : (r ?? "").replace(/\/$/, "");
12
+ return W && !H && !(U.pathname === W || U.pathname.startsWith(W + "/")) ? null : /* @__PURE__ */ c("div", {
13
13
  className: "flex min-h-full flex-col",
14
14
  children: /* @__PURE__ */ c(n, {
15
- fallback: /* @__PURE__ */ c(T, {}),
15
+ fallback: /* @__PURE__ */ c(V, {}),
16
16
  children: /* @__PURE__ */ l(o, { children: [
17
17
  /* @__PURE__ */ c(a, {
18
18
  index: !0,
@@ -78,6 +78,74 @@ var u = r(() => import("./pages/catalog/TitlesPage.js").then((e) => ({ default:
78
78
  path: "library/entitlements",
79
79
  element: /* @__PURE__ */ c(w, {})
80
80
  }),
81
+ /* @__PURE__ */ c(a, {
82
+ path: "browse",
83
+ element: /* @__PURE__ */ c(T, {})
84
+ }),
85
+ /* @__PURE__ */ c(a, {
86
+ path: "title/:id",
87
+ element: /* @__PURE__ */ c(E, {})
88
+ }),
89
+ /* @__PURE__ */ c(a, {
90
+ path: "watch/:titleId",
91
+ element: /* @__PURE__ */ c(D, {})
92
+ }),
93
+ /* @__PURE__ */ c(a, {
94
+ path: "watch/:titleId/episode/:episodeId",
95
+ element: /* @__PURE__ */ c(D, {})
96
+ }),
97
+ /* @__PURE__ */ c(a, {
98
+ path: "hooks",
99
+ element: /* @__PURE__ */ c(O, {})
100
+ }),
101
+ /* @__PURE__ */ c(a, {
102
+ path: "profiles",
103
+ element: /* @__PURE__ */ c(k, {})
104
+ }),
105
+ /* @__PURE__ */ c(a, {
106
+ path: "watch-party",
107
+ element: /* @__PURE__ */ c(A, {})
108
+ }),
109
+ /* @__PURE__ */ c(a, {
110
+ path: "watch-party/:id",
111
+ element: /* @__PURE__ */ c(j, {})
112
+ }),
113
+ /* @__PURE__ */ c(a, {
114
+ path: "checkout/:titleId",
115
+ element: /* @__PURE__ */ c(M, {})
116
+ }),
117
+ /* @__PURE__ */ c(a, {
118
+ path: "payouts",
119
+ element: /* @__PURE__ */ c(N, {})
120
+ }),
121
+ /* @__PURE__ */ c(a, {
122
+ path: "analytics",
123
+ element: /* @__PURE__ */ c(P, {})
124
+ }),
125
+ /* @__PURE__ */ c(a, {
126
+ path: "trust/moderation",
127
+ element: /* @__PURE__ */ c(F, {})
128
+ }),
129
+ /* @__PURE__ */ c(a, {
130
+ path: "onboarding/languages",
131
+ element: /* @__PURE__ */ c(I, {})
132
+ }),
133
+ /* @__PURE__ */ c(a, {
134
+ path: "developer",
135
+ element: /* @__PURE__ */ c(L, {})
136
+ }),
137
+ /* @__PURE__ */ c(a, {
138
+ path: "live",
139
+ element: /* @__PURE__ */ c(R, {})
140
+ }),
141
+ /* @__PURE__ */ c(a, {
142
+ path: "title/:id/localization",
143
+ element: /* @__PURE__ */ c(z, {})
144
+ }),
145
+ /* @__PURE__ */ c(a, {
146
+ path: "concierge",
147
+ element: /* @__PURE__ */ c(B, {})
148
+ }),
81
149
  /* @__PURE__ */ c(a, {
82
150
  path: "*",
83
151
  element: /* @__PURE__ */ c(i, {
@@ -90,6 +158,6 @@ var u = r(() => import("./pages/catalog/TitlesPage.js").then((e) => ({ default:
90
158
  });
91
159
  };
92
160
  //#endregion
93
- export { E as HookMoviesRoutes };
161
+ export { H as HookMoviesRoutes };
94
162
 
95
163
  //# sourceMappingURL=HookMoviesRoutes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"HookMoviesRoutes.js","names":[],"sources":["../../src/hookmovies/HookMoviesRoutes.tsx"],"sourcesContent":["/**\n * HookMovies Routes\n * @module hookmovies\n *\n * Real domain routes for the HookMovies workspace product: catalog (titles,\n * studios, people), production lifecycle, casting auditions, audience\n * engagement (reviews), rights & distribution, and the user library (lists +\n * entitlements). All data comes from the live `hookmovies` subgraph.\n */\n\nimport { type FC, lazy, Suspense } from 'react';\nimport { Routes, Route, Navigate, useLocation } from 'react-router-dom';\nimport { useHookMovies } from './context/HookMoviesContext';\n\n// Eager — primary landing\nimport { HomePage } from './pages/HomePage';\n\n// Catalog\nconst TitlesPage = lazy(() =>\n import('./pages/catalog/TitlesPage').then((m) => ({ default: m.TitlesPage }))\n);\nconst TitleCreatePage = lazy(() =>\n import('./pages/catalog/TitleCreatePage').then((m) => ({ default: m.TitleCreatePage }))\n);\nconst TitleDetailPage = lazy(() =>\n import('./pages/catalog/TitleDetailPage').then((m) => ({ default: m.TitleDetailPage }))\n);\nconst StudiosPage = lazy(() =>\n import('./pages/catalog/StudiosPage').then((m) => ({ default: m.StudiosPage }))\n);\nconst PeoplePage = lazy(() =>\n import('./pages/catalog/PeoplePage').then((m) => ({ default: m.PeoplePage }))\n);\n\n// Productions\nconst ProductionsPage = lazy(() =>\n import('./pages/productions/ProductionsPage').then((m) => ({ default: m.ProductionsPage }))\n);\nconst ProductionCreatePage = lazy(() =>\n import('./pages/productions/ProductionCreatePage').then((m) => ({\n default: m.ProductionCreatePage,\n }))\n);\nconst ProductionDetailPage = lazy(() =>\n import('./pages/productions/ProductionDetailPage').then((m) => ({\n default: m.ProductionDetailPage,\n }))\n);\n\n// Auditions\nconst AuditionsPage = lazy(() =>\n import('./pages/auditions/AuditionsPage').then((m) => ({ default: m.AuditionsPage }))\n);\nconst AuditionCreatePage = lazy(() =>\n import('./pages/auditions/AuditionCreatePage').then((m) => ({ default: m.AuditionCreatePage }))\n);\nconst AuditionDetailPage = lazy(() =>\n import('./pages/auditions/AuditionDetailPage').then((m) => ({ default: m.AuditionDetailPage }))\n);\n\n// Engagement\nconst ReviewsPage = lazy(() =>\n import('./pages/engagement/ReviewsPage').then((m) => ({ default: m.ReviewsPage }))\n);\n\n// Distribution\nconst RightsWindowsPage = lazy(() =>\n import('./pages/distribution/RightsWindowsPage').then((m) => ({ default: m.RightsWindowsPage }))\n);\n\n// Library\nconst ListsPage = lazy(() =>\n import('./pages/library/ListsPage').then((m) => ({ default: m.ListsPage }))\n);\nconst EntitlementsPage = lazy(() =>\n import('./pages/library/EntitlementsPage').then((m) => ({ default: m.EntitlementsPage }))\n);\n\nconst PageLoader: FC = () => (\n <div className=\"flex min-h-[400px] items-center justify-center\">\n <div className=\"h-8 w-8 animate-spin rounded-full border-b-2 border-action-primary-bg\" />\n </div>\n);\n\nexport const HookMoviesRoutes: FC = () => {\n const { basePath, isStandalone } = useHookMovies();\n const location = useLocation();\n\n const normalizedBasePath = basePath === '/' ? '' : (basePath ?? '').replace(/\\/$/, '');\n\n if (normalizedBasePath && !isStandalone) {\n const pathMatches =\n location.pathname === normalizedBasePath ||\n location.pathname.startsWith(normalizedBasePath + '/');\n\n if (!pathMatches) {\n return null;\n }\n }\n\n return (\n <div className=\"flex min-h-full flex-col\">\n <Suspense fallback={<PageLoader />}>\n <Routes>\n {/* Overview / dashboard */}\n <Route index element={<HomePage />} />\n\n {/* Catalog */}\n <Route path=\"catalog/titles\" element={<TitlesPage />} />\n <Route path=\"catalog/titles/new\" element={<TitleCreatePage />} />\n <Route path=\"catalog/titles/:id\" element={<TitleDetailPage />} />\n <Route path=\"catalog/studios\" element={<StudiosPage />} />\n <Route path=\"catalog/people\" element={<PeoplePage />} />\n\n {/* Productions */}\n <Route path=\"productions\" element={<ProductionsPage />} />\n <Route path=\"productions/new\" element={<ProductionCreatePage />} />\n <Route path=\"productions/:id\" element={<ProductionDetailPage />} />\n\n {/* Auditions */}\n <Route path=\"auditions\" element={<AuditionsPage />} />\n <Route path=\"auditions/new\" element={<AuditionCreatePage />} />\n <Route path=\"auditions/:id\" element={<AuditionDetailPage />} />\n\n {/* Engagement */}\n <Route path=\"engagement/reviews\" element={<ReviewsPage />} />\n\n {/* Distribution */}\n <Route path=\"distribution/rights\" element={<RightsWindowsPage />} />\n\n {/* Library */}\n <Route path=\"library/lists\" element={<ListsPage />} />\n <Route path=\"library/entitlements\" element={<EntitlementsPage />} />\n\n {/* Fallback */}\n <Route path=\"*\" element={<Navigate to=\"\" replace />} />\n </Routes>\n </Suspense>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"HookMoviesRoutes.js","names":[],"sources":["../../src/hookmovies/HookMoviesRoutes.tsx"],"sourcesContent":["/**\n * HookMovies Routes\n * @module hookmovies\n *\n * Real domain routes for the HookMovies workspace product: catalog (titles,\n * studios, people), production lifecycle, casting auditions, audience\n * engagement (reviews), rights & distribution, and the user library (lists +\n * entitlements). All data comes from the live `hookmovies` subgraph.\n */\n\nimport { type FC, lazy, Suspense } from 'react';\nimport { Routes, Route, Navigate, useLocation } from 'react-router-dom';\nimport { useHookMovies } from './context/HookMoviesContext';\n\n// Eager — primary landing\nimport { HomePage } from './pages/HomePage';\n\n// Catalog\nconst TitlesPage = lazy(() =>\n import('./pages/catalog/TitlesPage').then((m) => ({ default: m.TitlesPage }))\n);\nconst TitleCreatePage = lazy(() =>\n import('./pages/catalog/TitleCreatePage').then((m) => ({ default: m.TitleCreatePage }))\n);\nconst TitleDetailPage = lazy(() =>\n import('./pages/catalog/TitleDetailPage').then((m) => ({ default: m.TitleDetailPage }))\n);\nconst StudiosPage = lazy(() =>\n import('./pages/catalog/StudiosPage').then((m) => ({ default: m.StudiosPage }))\n);\nconst PeoplePage = lazy(() =>\n import('./pages/catalog/PeoplePage').then((m) => ({ default: m.PeoplePage }))\n);\n\n// Productions\nconst ProductionsPage = lazy(() =>\n import('./pages/productions/ProductionsPage').then((m) => ({ default: m.ProductionsPage }))\n);\nconst ProductionCreatePage = lazy(() =>\n import('./pages/productions/ProductionCreatePage').then((m) => ({\n default: m.ProductionCreatePage,\n }))\n);\nconst ProductionDetailPage = lazy(() =>\n import('./pages/productions/ProductionDetailPage').then((m) => ({\n default: m.ProductionDetailPage,\n }))\n);\n\n// Auditions\nconst AuditionsPage = lazy(() =>\n import('./pages/auditions/AuditionsPage').then((m) => ({ default: m.AuditionsPage }))\n);\nconst AuditionCreatePage = lazy(() =>\n import('./pages/auditions/AuditionCreatePage').then((m) => ({ default: m.AuditionCreatePage }))\n);\nconst AuditionDetailPage = lazy(() =>\n import('./pages/auditions/AuditionDetailPage').then((m) => ({ default: m.AuditionDetailPage }))\n);\n\n// Engagement\nconst ReviewsPage = lazy(() =>\n import('./pages/engagement/ReviewsPage').then((m) => ({ default: m.ReviewsPage }))\n);\n\n// Distribution\nconst RightsWindowsPage = lazy(() =>\n import('./pages/distribution/RightsWindowsPage').then((m) => ({ default: m.RightsWindowsPage }))\n);\n\n// Library\nconst ListsPage = lazy(() =>\n import('./pages/library/ListsPage').then((m) => ({ default: m.ListsPage }))\n);\nconst EntitlementsPage = lazy(() =>\n import('./pages/library/EntitlementsPage').then((m) => ({ default: m.EntitlementsPage }))\n);\n\n// Consumer (audience-facing) — discovery, title view, playback, hooks feed\nconst DiscoveryPage = lazy(() =>\n import('./pages/consumer/DiscoveryPage').then((m) => ({ default: m.DiscoveryPage }))\n);\nconst TitleViewPage = lazy(() =>\n import('./pages/consumer/TitleViewPage').then((m) => ({ default: m.TitleViewPage }))\n);\nconst PlayerPage = lazy(() =>\n import('./pages/consumer/PlayerPage').then((m) => ({ default: m.PlayerPage }))\n);\nconst HooksPage = lazy(() =>\n import('./pages/consumer/HooksPage').then((m) => ({ default: m.HooksPage }))\n);\n\n// Social — viewing profiles & synchronized watch parties\nconst ProfilesPage = lazy(() =>\n import('./pages/social/ProfilesPage').then((m) => ({ default: m.ProfilesPage }))\n);\nconst WatchPartyListPage = lazy(() =>\n import('./pages/social/WatchPartyListPage').then((m) => ({ default: m.WatchPartyListPage }))\n);\nconst WatchPartyRoomPage = lazy(() =>\n import('./pages/social/WatchPartyRoomPage').then((m) => ({ default: m.WatchPartyRoomPage }))\n);\n\n// Commerce — checkout (TVOD purchase / rental) & creator payouts\nconst CheckoutPage = lazy(() =>\n import('./pages/commerce/CheckoutPage').then((m) => ({ default: m.CheckoutPage }))\n);\nconst PayoutsPage = lazy(() =>\n import('./pages/analytics/PayoutsPage').then((m) => ({ default: m.PayoutsPage }))\n);\n\n// Analytics — creator / operator performance dashboards\nconst AnalyticsPage = lazy(() =>\n import('./pages/analytics/AnalyticsPage').then((m) => ({ default: m.AnalyticsPage }))\n);\n\n// Trust & safety — moderation queue\nconst ModerationPage = lazy(() =>\n import('./pages/trust/ModerationPage').then((m) => ({ default: m.ModerationPage }))\n);\n\n// Onboarding — language / content preferences\nconst OnboardingPage = lazy(() =>\n import('./pages/onboarding/OnboardingPage').then((m) => ({ default: m.OnboardingPage }))\n);\n\n// Developer portal — API keys\nconst DevPortalPage = lazy(() =>\n import('./pages/developer/DevPortalPage').then((m) => ({ default: m.DevPortalPage }))\n);\n\n// Live — FAST linear channels & schedules\nconst LivePage = lazy(() => import('./pages/live/LivePage').then((m) => ({ default: m.LivePage })));\n\n// Localization — per-title subtitle / caption / dub track management\nconst LocalizationPage = lazy(() =>\n import('./pages/localization/LocalizationPage').then((m) => ({ default: m.LocalizationPage }))\n);\n\n// AI — concierge / recommendations assistant\nconst ConciergePage = lazy(() =>\n import('./pages/ai/ConciergePage').then((m) => ({ default: m.ConciergePage }))\n);\n\nconst PageLoader: FC = () => (\n <div className=\"flex min-h-[400px] items-center justify-center\">\n <div className=\"h-8 w-8 animate-spin rounded-full border-b-2 border-action-primary-bg\" />\n </div>\n);\n\nexport const HookMoviesRoutes: FC = () => {\n const { basePath, isStandalone } = useHookMovies();\n const location = useLocation();\n\n const normalizedBasePath = basePath === '/' ? '' : (basePath ?? '').replace(/\\/$/, '');\n\n if (normalizedBasePath && !isStandalone) {\n const pathMatches =\n location.pathname === normalizedBasePath ||\n location.pathname.startsWith(normalizedBasePath + '/');\n\n if (!pathMatches) {\n return null;\n }\n }\n\n return (\n <div className=\"flex min-h-full flex-col\">\n <Suspense fallback={<PageLoader />}>\n <Routes>\n {/* Overview / dashboard */}\n <Route index element={<HomePage />} />\n\n {/* Catalog */}\n <Route path=\"catalog/titles\" element={<TitlesPage />} />\n <Route path=\"catalog/titles/new\" element={<TitleCreatePage />} />\n <Route path=\"catalog/titles/:id\" element={<TitleDetailPage />} />\n <Route path=\"catalog/studios\" element={<StudiosPage />} />\n <Route path=\"catalog/people\" element={<PeoplePage />} />\n\n {/* Productions */}\n <Route path=\"productions\" element={<ProductionsPage />} />\n <Route path=\"productions/new\" element={<ProductionCreatePage />} />\n <Route path=\"productions/:id\" element={<ProductionDetailPage />} />\n\n {/* Auditions */}\n <Route path=\"auditions\" element={<AuditionsPage />} />\n <Route path=\"auditions/new\" element={<AuditionCreatePage />} />\n <Route path=\"auditions/:id\" element={<AuditionDetailPage />} />\n\n {/* Engagement */}\n <Route path=\"engagement/reviews\" element={<ReviewsPage />} />\n\n {/* Distribution */}\n <Route path=\"distribution/rights\" element={<RightsWindowsPage />} />\n\n {/* Library */}\n <Route path=\"library/lists\" element={<ListsPage />} />\n <Route path=\"library/entitlements\" element={<EntitlementsPage />} />\n\n {/* Consumer (audience-facing) */}\n <Route path=\"browse\" element={<DiscoveryPage />} />\n <Route path=\"title/:id\" element={<TitleViewPage />} />\n <Route path=\"watch/:titleId\" element={<PlayerPage />} />\n <Route path=\"watch/:titleId/episode/:episodeId\" element={<PlayerPage />} />\n <Route path=\"hooks\" element={<HooksPage />} />\n\n {/* Social — profiles & watch parties */}\n <Route path=\"profiles\" element={<ProfilesPage />} />\n <Route path=\"watch-party\" element={<WatchPartyListPage />} />\n <Route path=\"watch-party/:id\" element={<WatchPartyRoomPage />} />\n\n {/* Commerce — checkout & payouts */}\n <Route path=\"checkout/:titleId\" element={<CheckoutPage />} />\n <Route path=\"payouts\" element={<PayoutsPage />} />\n\n {/* Analytics */}\n <Route path=\"analytics\" element={<AnalyticsPage />} />\n\n {/* Trust & safety */}\n <Route path=\"trust/moderation\" element={<ModerationPage />} />\n\n {/* Onboarding */}\n <Route path=\"onboarding/languages\" element={<OnboardingPage />} />\n\n {/* Developer portal */}\n <Route path=\"developer\" element={<DevPortalPage />} />\n\n {/* Live — FAST channels */}\n <Route path=\"live\" element={<LivePage />} />\n\n {/* Localization */}\n <Route path=\"title/:id/localization\" element={<LocalizationPage />} />\n\n {/* AI concierge */}\n <Route path=\"concierge\" element={<ConciergePage />} />\n\n {/* Fallback */}\n <Route path=\"*\" element={<Navigate to=\"\" replace />} />\n </Routes>\n </Suspense>\n </div>\n );\n};\n"],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import "./PageLayout.js";
2
+ import "./MetricsCard.js";
3
+ import "./StatusBadge.js";
4
+ import "./EmptyState.js";
5
+ import "./StateViews.js";
6
+ import "./Pagination.js";
7
+ import "./RatingDisplay.js";
@@ -1,85 +1,109 @@
1
1
  import { joinPath as e } from "../utils/navigation.js";
2
- import { createContext as t, useCallback as n, useContext as r, useMemo as i } from "react";
3
- import { MemoryRouter as a, useNavigate as o } from "react-router-dom";
4
- import { jsx as s } from "react/jsx-runtime";
2
+ import { createContext as t, useCallback as n, useContext as r, useMemo as i, useState as a } from "react";
3
+ import { MemoryRouter as o, useNavigate as s } from "react-router-dom";
4
+ import { jsx as c } from "react/jsx-runtime";
5
5
  //#region src/hookmovies/context/HookMoviesContext.tsx
6
- var c = t(null);
7
- function l() {
8
- let e = r(c);
6
+ var l = t(null), u = (e) => `hookmovies:activeProfile:${e ?? "default"}`, d = (e) => {
7
+ if (typeof window > "u") return null;
8
+ try {
9
+ return window.localStorage.getItem(u(e));
10
+ } catch {
11
+ return null;
12
+ }
13
+ };
14
+ function f(e) {
15
+ let [t, r] = a(() => d(e));
16
+ return [t, n((t) => {
17
+ if (r(t), !(typeof window > "u")) try {
18
+ let n = u(e);
19
+ t ? window.localStorage.setItem(n, t) : window.localStorage.removeItem(n);
20
+ } catch {}
21
+ }, [e])];
22
+ }
23
+ function p() {
24
+ let e = r(l);
9
25
  if (!e) throw Error("useHookMovies must be used within a HookMoviesProvider");
10
26
  return e;
11
27
  }
12
- var u = ({ children: t, basePath: r, currentUser: a, tenantId: l, workspaceId: u, apiGatewayUrl: d, authToken: f }) => {
13
- let p = o(), m = r || "/", h = n((t) => e(m, t), [m]), g = n((t) => {
14
- p(e(m, t));
15
- }, [m, p]), _ = i(() => ({
16
- basePath: m,
28
+ var m = ({ children: t, basePath: r, currentUser: a, tenantId: o, workspaceId: u, apiGatewayUrl: d, authToken: p }) => {
29
+ let m = s(), h = r || "/", [g, _] = f(u), v = n((t) => e(h, t), [h]), y = n((t) => {
30
+ m(e(h, t));
31
+ }, [h, m]), b = i(() => ({
32
+ basePath: h,
17
33
  navigate: void 0,
18
34
  currentUser: a,
19
- tenantId: l,
35
+ tenantId: o,
20
36
  workspaceId: u,
21
37
  apiGatewayUrl: d,
22
- authToken: f,
38
+ authToken: p,
23
39
  isStandalone: !0,
24
- navigateTo: g,
25
- getPath: h
40
+ navigateTo: y,
41
+ getPath: v,
42
+ activeProfileId: g,
43
+ setActiveProfile: _
26
44
  }), [
27
- m,
45
+ h,
28
46
  a,
29
- l,
47
+ o,
30
48
  u,
31
49
  d,
32
- f,
50
+ p,
51
+ y,
52
+ v,
33
53
  g,
34
- h
54
+ _
35
55
  ]);
36
- return /* @__PURE__ */ s(c.Provider, {
37
- value: _,
56
+ return /* @__PURE__ */ c(l.Provider, {
57
+ value: b,
38
58
  children: t
39
59
  });
40
- }, d = ({ children: t, basePath: r, navigate: a, currentUser: o, tenantId: l, workspaceId: u, apiGatewayUrl: d, authToken: f }) => {
41
- let p = r || "/", m = n((t) => e(p, t), [p]), h = n((t) => {
42
- a(e(p, t));
43
- }, [p, a]), g = i(() => ({
44
- basePath: p,
60
+ }, h = ({ children: t, basePath: r, navigate: a, currentUser: o, tenantId: s, workspaceId: u, apiGatewayUrl: d, authToken: p }) => {
61
+ let m = r || "/", [h, g] = f(u), _ = n((t) => e(m, t), [m]), v = n((t) => {
62
+ a(e(m, t));
63
+ }, [m, a]), y = i(() => ({
64
+ basePath: m,
45
65
  navigate: a,
46
66
  currentUser: o,
47
- tenantId: l,
67
+ tenantId: s,
48
68
  workspaceId: u,
49
69
  apiGatewayUrl: d,
50
- authToken: f,
70
+ authToken: p,
51
71
  isStandalone: !1,
52
- navigateTo: h,
53
- getPath: m
72
+ navigateTo: v,
73
+ getPath: _,
74
+ activeProfileId: h,
75
+ setActiveProfile: g
54
76
  }), [
55
- p,
77
+ m,
56
78
  a,
57
79
  o,
58
- l,
80
+ s,
59
81
  u,
60
82
  d,
61
- f,
83
+ p,
84
+ v,
85
+ _,
62
86
  h,
63
- m
87
+ g
64
88
  ]);
65
- return /* @__PURE__ */ s(c.Provider, {
66
- value: g,
89
+ return /* @__PURE__ */ c(l.Provider, {
90
+ value: y,
67
91
  children: t
68
92
  });
69
- }, f = (e) => {
93
+ }, g = (e) => {
70
94
  let { children: t, navigate: n } = e;
71
- return n ? /* @__PURE__ */ s(d, {
95
+ return n ? /* @__PURE__ */ c(h, {
72
96
  ...e,
73
97
  navigate: n,
74
98
  isStandalone: !1,
75
99
  children: t
76
- }) : /* @__PURE__ */ s(a, { children: /* @__PURE__ */ s(u, {
100
+ }) : /* @__PURE__ */ c(o, { children: /* @__PURE__ */ c(m, {
77
101
  ...e,
78
102
  isStandalone: !0,
79
103
  children: t
80
104
  }) });
81
105
  };
82
106
  //#endregion
83
- export { f as HookMoviesProvider, l as useHookMovies };
107
+ export { g as HookMoviesProvider, p as useHookMovies };
84
108
 
85
109
  //# sourceMappingURL=HookMoviesContext.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"HookMoviesContext.js","names":[],"sources":["../../../src/hookmovies/context/HookMoviesContext.tsx"],"sourcesContent":["/**\n * HookMovies Context Provider\n * @module hookmovies/context\n */\n\nimport type { FC, PropsWithChildren } from 'react';\nimport { createContext, useContext, useMemo, useCallback } from 'react';\nimport { MemoryRouter, useNavigate as useRouterNavigate } from 'react-router-dom';\nimport type { HookMoviesRootProps } from '../types';\nimport { joinPath } from '../utils/navigation';\n\n// ============================================================================\n// Context\n// ============================================================================\n\ninterface HookMoviesContextValue extends Omit<\n HookMoviesRootProps,\n 'registerNavItems' | 'registerFooterItems' | 'navigate'\n> {\n isStandalone: boolean;\n /** Shell's navigate function (only available in integrated mode) */\n navigate?: (path: string) => void;\n /** Navigate to a path relative to basePath */\n navigateTo: (relativePath: string) => void;\n /** Get the full path for a relative path */\n getPath: (relativePath: string) => string;\n}\n\nconst HookMoviesContext = createContext<HookMoviesContextValue | null>(null);\n\n// ============================================================================\n// Hook\n// ============================================================================\n\nexport function useHookMovies(): HookMoviesContextValue {\n const context = useContext(HookMoviesContext);\n if (!context) {\n throw new Error('useHookMovies must be used within a HookMoviesProvider');\n }\n return context;\n}\n\n// ============================================================================\n// Provider Component\n// ============================================================================\n\ntype ProviderProps = Omit<HookMoviesRootProps, 'registerNavItems' | 'registerFooterItems'> & {\n isStandalone: boolean;\n};\n\n/** Provider for standalone mode (has access to MemoryRouter) */\nconst StandaloneProviderInner: FC<PropsWithChildren<ProviderProps>> = ({\n children,\n basePath,\n currentUser,\n tenantId,\n workspaceId,\n apiGatewayUrl,\n authToken,\n}) => {\n const routerNavigate = useRouterNavigate();\n const effectiveBasePath = basePath || '/';\n\n const getPath = useCallback(\n (relativePath: string) => joinPath(effectiveBasePath, relativePath),\n [effectiveBasePath]\n );\n\n const navigateTo = useCallback(\n (relativePath: string) => {\n const fullPath = joinPath(effectiveBasePath, relativePath);\n routerNavigate(fullPath);\n },\n [effectiveBasePath, routerNavigate]\n );\n\n const contextValue = useMemo<HookMoviesContextValue>(\n () => ({\n basePath: effectiveBasePath,\n navigate: undefined,\n currentUser,\n tenantId,\n workspaceId,\n apiGatewayUrl,\n authToken,\n isStandalone: true,\n navigateTo,\n getPath,\n }),\n [\n effectiveBasePath,\n currentUser,\n tenantId,\n workspaceId,\n apiGatewayUrl,\n authToken,\n navigateTo,\n getPath,\n ]\n );\n\n return <HookMoviesContext.Provider value={contextValue}>{children}</HookMoviesContext.Provider>;\n};\n\n/** Provider for integrated mode (shell provides navigate) */\nconst IntegratedProviderInner: FC<\n PropsWithChildren<ProviderProps & { navigate: (path: string) => void }>\n> = ({\n children,\n basePath,\n navigate,\n currentUser,\n tenantId,\n workspaceId,\n apiGatewayUrl,\n authToken,\n}) => {\n const effectiveBasePath = basePath || '/';\n\n const getPath = useCallback(\n (relativePath: string) => joinPath(effectiveBasePath, relativePath),\n [effectiveBasePath]\n );\n\n const navigateTo = useCallback(\n (relativePath: string) => {\n const fullPath = joinPath(effectiveBasePath, relativePath);\n navigate(fullPath);\n },\n [effectiveBasePath, navigate]\n );\n\n const contextValue = useMemo<HookMoviesContextValue>(\n () => ({\n basePath: effectiveBasePath,\n navigate,\n currentUser,\n tenantId,\n workspaceId,\n apiGatewayUrl,\n authToken,\n isStandalone: false,\n navigateTo,\n getPath,\n }),\n [\n effectiveBasePath,\n navigate,\n currentUser,\n tenantId,\n workspaceId,\n apiGatewayUrl,\n authToken,\n navigateTo,\n getPath,\n ]\n );\n\n return <HookMoviesContext.Provider value={contextValue}>{children}</HookMoviesContext.Provider>;\n};\n\nexport const HookMoviesProvider: FC<PropsWithChildren<HookMoviesRootProps>> = (props) => {\n const { children, navigate } = props;\n // Standalone mode: no navigate function provided (MFE manages its own router)\n // Integrated mode: navigate function provided by shell (shell provides router)\n const isStandalone = !navigate;\n\n // Standalone mode: wrap in MemoryRouter\n if (isStandalone) {\n return (\n <MemoryRouter>\n <StandaloneProviderInner {...props} isStandalone={true}>\n {children}\n </StandaloneProviderInner>\n </MemoryRouter>\n );\n }\n\n // Integrated mode: shell provides router\n return (\n <IntegratedProviderInner {...props} navigate={navigate} isStandalone={false}>\n {children}\n </IntegratedProviderInner>\n );\n};\n"],"mappings":";;;;;AA4BA,IAAM,IAAoB,EAA6C,KAAK;AAM5E,SAAgB,IAAwC;CACtD,IAAM,IAAU,EAAW,EAAkB;AAC7C,KAAI,CAAC,EACH,OAAU,MAAM,yDAAyD;AAE3E,QAAO;;AAYT,IAAM,KAAiE,EACrE,aACA,aACA,gBACA,aACA,gBACA,kBACA,mBACI;CACJ,IAAM,IAAiB,GAAmB,EACpC,IAAoB,KAAY,KAEhC,IAAU,GACb,MAAyB,EAAS,GAAmB,EAAa,EACnE,CAAC,EAAkB,CACpB,EAEK,IAAa,GAChB,MAAyB;AAExB,IADiB,EAAS,GAAmB,EAAa,CAClC;IAE1B,CAAC,GAAmB,EAAe,CACpC,EAEK,IAAe,SACZ;EACL,UAAU;EACV,UAAU,KAAA;EACV;EACA;EACA;EACA;EACA;EACA,cAAc;EACd;EACA;EACD,GACD;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CACF;AAED,QAAO,kBAAC,EAAkB,UAAnB;EAA4B,OAAO;EAAe;EAAsC,CAAA;GAI3F,KAED,EACH,aACA,aACA,aACA,gBACA,aACA,gBACA,kBACA,mBACI;CACJ,IAAM,IAAoB,KAAY,KAEhC,IAAU,GACb,MAAyB,EAAS,GAAmB,EAAa,EACnE,CAAC,EAAkB,CACpB,EAEK,IAAa,GAChB,MAAyB;AAExB,IADiB,EAAS,GAAmB,EAAa,CACxC;IAEpB,CAAC,GAAmB,EAAS,CAC9B,EAEK,IAAe,SACZ;EACL,UAAU;EACV;EACA;EACA;EACA;EACA;EACA;EACA,cAAc;EACd;EACA;EACD,GACD;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CACF;AAED,QAAO,kBAAC,EAAkB,UAAnB;EAA4B,OAAO;EAAe;EAAsC,CAAA;GAGpF,KAAkE,MAAU;CACvF,IAAM,EAAE,aAAU,gBAAa;AAiB/B,QAdsB,IAepB,kBAAC,GAAD;EAAyB,GAAI;EAAiB;EAAU,cAAc;EACnE;EACuB,CAAA,GAZxB,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;EAAyB,GAAI;EAAO,cAAc;EAC/C;EACuB,CAAA,EACb,CAAA"}
1
+ {"version":3,"file":"HookMoviesContext.js","names":[],"sources":["../../../src/hookmovies/context/HookMoviesContext.tsx"],"sourcesContent":["/**\n * HookMovies Context Provider\n * @module hookmovies/context\n */\n\nimport type { FC, PropsWithChildren } from 'react';\nimport { createContext, useContext, useMemo, useCallback, useState } from 'react';\nimport { MemoryRouter, useNavigate as useRouterNavigate } from 'react-router-dom';\nimport type { HookMoviesRootProps } from '../types';\nimport { joinPath } from '../utils/navigation';\n\n// ============================================================================\n// Context\n// ============================================================================\n\ninterface HookMoviesContextValue extends Omit<\n HookMoviesRootProps,\n 'registerNavItems' | 'registerFooterItems' | 'navigate'\n> {\n isStandalone: boolean;\n /** Shell's navigate function (only available in integrated mode) */\n navigate?: (path: string) => void;\n /** Navigate to a path relative to basePath */\n navigateTo: (relativePath: string) => void;\n /** Get the full path for a relative path */\n getPath: (relativePath: string) => string;\n /**\n * Id of the currently selected viewing profile (Netflix-style per-account\n * profile), or `null` when none is chosen. Persisted to localStorage,\n * scoped per workspace. Consumer surfaces gate on this (e.g. the player and\n * discovery use it to apply the profile's language / maturity preferences).\n */\n activeProfileId: string | null;\n /** Select (or clear, with `null`) the active viewing profile; persists it. */\n setActiveProfile: (profileId: string | null) => void;\n}\n\nconst HookMoviesContext = createContext<HookMoviesContextValue | null>(null);\n\n// ============================================================================\n// Active profile persistence (localStorage, workspace-scoped)\n// ============================================================================\n\nconst activeProfileStorageKey = (workspaceId?: string): string =>\n `hookmovies:activeProfile:${workspaceId ?? 'default'}`;\n\nconst readStoredActiveProfile = (workspaceId?: string): string | null => {\n if (typeof window === 'undefined') return null;\n try {\n return window.localStorage.getItem(activeProfileStorageKey(workspaceId));\n } catch {\n return null;\n }\n};\n\n/**\n * State + persistence for the active viewing profile. Reads the initial value\n * from localStorage (per workspace) and writes through on every change.\n */\nfunction useActiveProfileState(\n workspaceId?: string\n): [string | null, (profileId: string | null) => void] {\n const [activeProfileId, setActiveProfileId] = useState<string | null>(() =>\n readStoredActiveProfile(workspaceId)\n );\n\n const setActiveProfile = useCallback(\n (profileId: string | null) => {\n setActiveProfileId(profileId);\n if (typeof window === 'undefined') return;\n try {\n const key = activeProfileStorageKey(workspaceId);\n if (profileId) {\n window.localStorage.setItem(key, profileId);\n } else {\n window.localStorage.removeItem(key);\n }\n } catch {\n // Ignore storage failures (private mode / quota) — in-memory state still works.\n }\n },\n [workspaceId]\n );\n\n return [activeProfileId, setActiveProfile];\n}\n\n// ============================================================================\n// Hook\n// ============================================================================\n\nexport function useHookMovies(): HookMoviesContextValue {\n const context = useContext(HookMoviesContext);\n if (!context) {\n throw new Error('useHookMovies must be used within a HookMoviesProvider');\n }\n return context;\n}\n\n// ============================================================================\n// Provider Component\n// ============================================================================\n\ntype ProviderProps = Omit<HookMoviesRootProps, 'registerNavItems' | 'registerFooterItems'> & {\n isStandalone: boolean;\n};\n\n/** Provider for standalone mode (has access to MemoryRouter) */\nconst StandaloneProviderInner: FC<PropsWithChildren<ProviderProps>> = ({\n children,\n basePath,\n currentUser,\n tenantId,\n workspaceId,\n apiGatewayUrl,\n authToken,\n}) => {\n const routerNavigate = useRouterNavigate();\n const effectiveBasePath = basePath || '/';\n const [activeProfileId, setActiveProfile] = useActiveProfileState(workspaceId);\n\n const getPath = useCallback(\n (relativePath: string) => joinPath(effectiveBasePath, relativePath),\n [effectiveBasePath]\n );\n\n const navigateTo = useCallback(\n (relativePath: string) => {\n const fullPath = joinPath(effectiveBasePath, relativePath);\n routerNavigate(fullPath);\n },\n [effectiveBasePath, routerNavigate]\n );\n\n const contextValue = useMemo<HookMoviesContextValue>(\n () => ({\n basePath: effectiveBasePath,\n navigate: undefined,\n currentUser,\n tenantId,\n workspaceId,\n apiGatewayUrl,\n authToken,\n isStandalone: true,\n navigateTo,\n getPath,\n activeProfileId,\n setActiveProfile,\n }),\n [\n effectiveBasePath,\n currentUser,\n tenantId,\n workspaceId,\n apiGatewayUrl,\n authToken,\n navigateTo,\n getPath,\n activeProfileId,\n setActiveProfile,\n ]\n );\n\n return <HookMoviesContext.Provider value={contextValue}>{children}</HookMoviesContext.Provider>;\n};\n\n/** Provider for integrated mode (shell provides navigate) */\nconst IntegratedProviderInner: FC<\n PropsWithChildren<ProviderProps & { navigate: (path: string) => void }>\n> = ({\n children,\n basePath,\n navigate,\n currentUser,\n tenantId,\n workspaceId,\n apiGatewayUrl,\n authToken,\n}) => {\n const effectiveBasePath = basePath || '/';\n const [activeProfileId, setActiveProfile] = useActiveProfileState(workspaceId);\n\n const getPath = useCallback(\n (relativePath: string) => joinPath(effectiveBasePath, relativePath),\n [effectiveBasePath]\n );\n\n const navigateTo = useCallback(\n (relativePath: string) => {\n const fullPath = joinPath(effectiveBasePath, relativePath);\n navigate(fullPath);\n },\n [effectiveBasePath, navigate]\n );\n\n const contextValue = useMemo<HookMoviesContextValue>(\n () => ({\n basePath: effectiveBasePath,\n navigate,\n currentUser,\n tenantId,\n workspaceId,\n apiGatewayUrl,\n authToken,\n isStandalone: false,\n navigateTo,\n getPath,\n activeProfileId,\n setActiveProfile,\n }),\n [\n effectiveBasePath,\n navigate,\n currentUser,\n tenantId,\n workspaceId,\n apiGatewayUrl,\n authToken,\n navigateTo,\n getPath,\n activeProfileId,\n setActiveProfile,\n ]\n );\n\n return <HookMoviesContext.Provider value={contextValue}>{children}</HookMoviesContext.Provider>;\n};\n\nexport const HookMoviesProvider: FC<PropsWithChildren<HookMoviesRootProps>> = (props) => {\n const { children, navigate } = props;\n // Standalone mode: no navigate function provided (MFE manages its own router)\n // Integrated mode: navigate function provided by shell (shell provides router)\n const isStandalone = !navigate;\n\n // Standalone mode: wrap in MemoryRouter\n if (isStandalone) {\n return (\n <MemoryRouter>\n <StandaloneProviderInner {...props} isStandalone={true}>\n {children}\n </StandaloneProviderInner>\n </MemoryRouter>\n );\n }\n\n // Integrated mode: shell provides router\n return (\n <IntegratedProviderInner {...props} navigate={navigate} isStandalone={false}>\n {children}\n </IntegratedProviderInner>\n );\n};\n"],"mappings":";;;;;AAqCA,IAAM,IAAoB,EAA6C,KAAK,EAMtE,KAA2B,MAC/B,4BAA4B,KAAe,aAEvC,KAA2B,MAAwC;AACvE,KAAI,OAAO,SAAW,IAAa,QAAO;AAC1C,KAAI;AACF,SAAO,OAAO,aAAa,QAAQ,EAAwB,EAAY,CAAC;SAClE;AACN,SAAO;;;AAQX,SAAS,EACP,GACqD;CACrD,IAAM,CAAC,GAAiB,KAAsB,QAC5C,EAAwB,EAAY,CACrC;AAoBD,QAAO,CAAC,GAlBiB,GACtB,MAA6B;AAC5B,QAAmB,EAAU,EACzB,SAAO,SAAW,KACtB,KAAI;GACF,IAAM,IAAM,EAAwB,EAAY;AAChD,GAAI,IACF,OAAO,aAAa,QAAQ,GAAK,EAAU,GAE3C,OAAO,aAAa,WAAW,EAAI;UAE/B;IAIV,CAAC,EAAY,CACd,CAEyC;;AAO5C,SAAgB,IAAwC;CACtD,IAAM,IAAU,EAAW,EAAkB;AAC7C,KAAI,CAAC,EACH,OAAU,MAAM,yDAAyD;AAE3E,QAAO;;AAYT,IAAM,KAAiE,EACrE,aACA,aACA,gBACA,aACA,gBACA,kBACA,mBACI;CACJ,IAAM,IAAiB,GAAmB,EACpC,IAAoB,KAAY,KAChC,CAAC,GAAiB,KAAoB,EAAsB,EAAY,EAExE,IAAU,GACb,MAAyB,EAAS,GAAmB,EAAa,EACnE,CAAC,EAAkB,CACpB,EAEK,IAAa,GAChB,MAAyB;AAExB,IADiB,EAAS,GAAmB,EAAa,CAClC;IAE1B,CAAC,GAAmB,EAAe,CACpC,EAEK,IAAe,SACZ;EACL,UAAU;EACV,UAAU,KAAA;EACV;EACA;EACA;EACA;EACA;EACA,cAAc;EACd;EACA;EACA;EACA;EACD,GACD;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CACF;AAED,QAAO,kBAAC,EAAkB,UAAnB;EAA4B,OAAO;EAAe;EAAsC,CAAA;GAI3F,KAED,EACH,aACA,aACA,aACA,gBACA,aACA,gBACA,kBACA,mBACI;CACJ,IAAM,IAAoB,KAAY,KAChC,CAAC,GAAiB,KAAoB,EAAsB,EAAY,EAExE,IAAU,GACb,MAAyB,EAAS,GAAmB,EAAa,EACnE,CAAC,EAAkB,CACpB,EAEK,IAAa,GAChB,MAAyB;AAExB,IADiB,EAAS,GAAmB,EAAa,CACxC;IAEpB,CAAC,GAAmB,EAAS,CAC9B,EAEK,IAAe,SACZ;EACL,UAAU;EACV;EACA;EACA;EACA;EACA;EACA;EACA,cAAc;EACd;EACA;EACA;EACA;EACD,GACD;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CACF;AAED,QAAO,kBAAC,EAAkB,UAAnB;EAA4B,OAAO;EAAe;EAAsC,CAAA;GAGpF,KAAkE,MAAU;CACvF,IAAM,EAAE,aAAU,gBAAa;AAiB/B,QAdsB,IAepB,kBAAC,GAAD;EAAyB,GAAI;EAAiB;EAAU,cAAc;EACnE;EACuB,CAAA,GAZxB,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;EAAyB,GAAI;EAAO,cAAc;EAC/C;EACuB,CAAA,EACb,CAAA"}
@@ -1,55 +1,59 @@
1
+ import { useHookMovies as e } from "../context/HookMoviesContext.js";
1
2
  import "../context/index.js";
2
- import "@tanstack/react-query";
3
- import { graphqlFetch as e } from "@burdenoff/fe-libs/shared/graphql";
3
+ import { useQuery as t } from "@tanstack/react-query";
4
+ import { graphqlFetch as n } from "@burdenoff/fe-libs/shared/graphql";
4
5
  //#region src/hookmovies/hooks/useFiles.ts
5
- var t = 21600, n = {
6
+ var r = 21600, i = {
6
7
  selfTapes: "/HookMovies/SelfTapes",
7
- episodes: "/HookMovies/Episodes"
8
+ episodes: "/HookMovies/Episodes",
9
+ artwork: "/HookMovies/Artwork",
10
+ masters: "/HookMovies/Masters",
11
+ clips: "/HookMovies/Clips"
8
12
  };
9
- async function r(t, n) {
10
- let r = await e({
13
+ async function a(e, t) {
14
+ let r = await n({
11
15
  gateway: "workspace",
12
- query: t,
13
- variables: n,
16
+ query: e,
17
+ variables: t,
14
18
  workspaceToken: !0
15
19
  });
16
20
  if (r.errors?.length) throw Error(r.errors[0]?.message ?? "Files request failed");
17
21
  if (!r.data) throw Error("Files response did not include data");
18
22
  return r.data;
19
23
  }
20
- var i = "\n mutation HokEnsureFolder($path: String!) {\n ensureFolderByPath(path: $path) { id }\n }\n", a = "\n mutation HokInitiateUpload($input: InitiateUploadInput!) {\n initiateUpload(input: $input) {\n uploadUrl\n session { id }\n }\n }\n", o = "\n mutation HokCompleteUpload($input: CompleteUploadInput!) {\n completeUpload(input: $input) {\n fileId\n file { id name }\n }\n }\n", s = "\n query HokGetFileDownloadUrl($id: ID!, $expiresIn: Int) {\n getFileDownloadUrl(id: $id, expiresIn: $expiresIn)\n }\n";
21
- function c(e, t) {
24
+ var o = "\n mutation HokEnsureFolder($path: String!) {\n ensureFolderByPath(path: $path) { id }\n }\n", s = "\n mutation HokInitiateUpload($input: InitiateUploadInput!) {\n initiateUpload(input: $input) {\n uploadUrl\n session { id }\n }\n }\n", c = "\n mutation HokCompleteUpload($input: CompleteUploadInput!) {\n completeUpload(input: $input) {\n fileId\n file { id name }\n }\n }\n", l = "\n query HokGetFileDownloadUrl($id: ID!, $expiresIn: Int) {\n getFileDownloadUrl(id: $id, expiresIn: $expiresIn)\n }\n";
25
+ function u(e, t) {
22
26
  let n = e.lastIndexOf(".");
23
27
  return n > -1 && n < e.length - 1 ? e.slice(n + 1).toLowerCase() : (t.split("/")[1] ?? "bin").toLowerCase();
24
28
  }
25
- async function l(e, n) {
26
- let l = (await r(i, { path: n })).ensureFolderByPath?.id;
27
- if (!l) throw Error("Could not resolve the upload folder.");
28
- let u = e.type || "application/octet-stream", d = e.size, f = await r(a, { input: {
29
+ async function d(e, t) {
30
+ let n = (await a(o, { path: t })).ensureFolderByPath?.id;
31
+ if (!n) throw Error("Could not resolve the upload folder.");
32
+ let i = e.type || "application/octet-stream", d = e.size, f = await a(s, { input: {
29
33
  fileName: e.name,
30
- extension: c(e.name, u),
34
+ extension: u(e.name, i),
31
35
  fileSize: d,
32
- mimeType: u,
33
- folderId: l
36
+ mimeType: i,
37
+ folderId: n
34
38
  } }), p = f.initiateUpload?.uploadUrl, m = f.initiateUpload?.session.id;
35
39
  if (!p || !m) throw Error("The files service did not return an upload URL.");
36
40
  let h = await fetch(p, {
37
41
  method: "PUT",
38
42
  body: e,
39
- headers: { "Content-Type": u }
43
+ headers: { "Content-Type": i }
40
44
  });
41
45
  if (!h.ok) throw Error(`Upload to storage failed (${h.status}).`);
42
- let g = (await r(o, { input: {
46
+ let g = (await a(c, { input: {
43
47
  sessionId: m,
44
48
  fileSize: d,
45
- folderId: l
49
+ folderId: n
46
50
  } })).completeUpload?.file;
47
51
  if (!g?.id) throw Error("The upload could not be finalized.");
48
52
  let _ = "";
49
53
  try {
50
- _ = (await r(s, {
54
+ _ = (await a(l, {
51
55
  id: g.id,
52
- expiresIn: t
56
+ expiresIn: r
53
57
  })).getFileDownloadUrl ?? "";
54
58
  } catch {
55
59
  _ = "";
@@ -60,7 +64,34 @@ async function l(e, n) {
60
64
  name: g.name
61
65
  };
62
66
  }
67
+ function f(i) {
68
+ let { apiGatewayUrl: a } = e();
69
+ return t({
70
+ queryKey: [
71
+ "hookmovies",
72
+ "file-url",
73
+ i ?? ""
74
+ ],
75
+ enabled: !!i,
76
+ staleTime: 1800 * 1e3,
77
+ retry: 1,
78
+ queryFn: async () => {
79
+ let e = await n({
80
+ gateway: "workspace",
81
+ baseUrl: a,
82
+ workspaceToken: !0,
83
+ query: l,
84
+ variables: {
85
+ id: i,
86
+ expiresIn: r
87
+ }
88
+ });
89
+ if (e.errors?.length) throw Error(e.errors[0]?.message ?? "Could not resolve file URL");
90
+ return e.data?.getFileDownloadUrl ?? null;
91
+ }
92
+ });
93
+ }
63
94
  //#endregion
64
- export { n as FILE_FOLDERS, l as uploadFileToFiles };
95
+ export { i as FILE_FOLDERS, d as uploadFileToFiles, f as useFileUrl };
65
96
 
66
97
  //# sourceMappingURL=useFiles.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useFiles.js","names":[],"sources":["../../../src/hookmovies/hooks/useFiles.ts"],"sourcesContent":["/**\n * File hooks — self-tapes & episode masters via wspace-files-svc (NO duplication).\n * @module hookmovies/hooks\n *\n * HookMovies never stores blobs. Episodes (master/mezzanine) and audition\n * self-tapes reference files owned by wspace-files-svc by id. Upload uses the\n * SAME proven `graphqlFetch` transport as every other read/write in this MFE\n * (the shell's workspace gateway + token), driving the wspace-files 3-step\n * presigned flow directly:\n * ensureFolderByPath -> initiateUpload -> HTTP PUT -> completeUpload\n * Display resolves a file id to a presigned URL via `getFileDownloadUrl`.\n *\n * NOTE: we deliberately do NOT use the Apollo-based `uploadBlobToFiles` /\n * `getWorkspaceClient()` helper here — this shell wires its data plane through\n * `graphqlFetch`, not a global Apollo client, so `getWorkspaceClient()` returns\n * an un-networked client and the upload silently no-ops. `graphqlFetch` is the\n * transport the whole MFE already uses successfully.\n */\n\nimport { useQuery } from '@tanstack/react-query';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\n\nimport { useHookMovies } from '../context';\n\n/**\n * Six hours. wspace-files-svc rejects any `expiresIn` above the S3 7-day cap\n * (604800s) with an INTERNAL_SERVER_ERROR, so we deliberately stay well under\n * it — these URLs back immediate preview/download, not durable references.\n */\nconst DOWNLOAD_URL_TTL_SECONDS = 21_600;\n\nexport const FILE_FOLDERS = {\n selfTapes: '/HookMovies/SelfTapes',\n episodes: '/HookMovies/Episodes',\n} as const;\n\nexport interface UploadedFile {\n id: string;\n url: string;\n name: string;\n}\n\n/** Thin wrapper over the workspace gateway using the MFE's proven transport. */\nasync function filesFetch<TData>(\n query: string,\n variables: Record<string, unknown>\n): Promise<TData> {\n const response = await graphqlFetch<TData>({\n gateway: 'workspace',\n query,\n variables,\n workspaceToken: true,\n });\n if (response.errors?.length) {\n throw new Error(response.errors[0]?.message ?? 'Files request failed');\n }\n if (!response.data) {\n throw new Error('Files response did not include data');\n }\n return response.data;\n}\n\nconst ENSURE_FOLDER = `\n mutation HokEnsureFolder($path: String!) {\n ensureFolderByPath(path: $path) { id }\n }\n`;\n\nconst INITIATE_UPLOAD = `\n mutation HokInitiateUpload($input: InitiateUploadInput!) {\n initiateUpload(input: $input) {\n uploadUrl\n session { id }\n }\n }\n`;\n\nconst COMPLETE_UPLOAD = `\n mutation HokCompleteUpload($input: CompleteUploadInput!) {\n completeUpload(input: $input) {\n fileId\n file { id name }\n }\n }\n`;\n\nconst GET_FILE_DOWNLOAD_URL = `\n query HokGetFileDownloadUrl($id: ID!, $expiresIn: Int) {\n getFileDownloadUrl(id: $id, expiresIn: $expiresIn)\n }\n`;\n\nfunction fileExtension(name: string, mimeType: string): string {\n const dot = name.lastIndexOf('.');\n if (dot > -1 && dot < name.length - 1) return name.slice(dot + 1).toLowerCase();\n const fromMime = mimeType.split('/')[1];\n return (fromMime ?? 'bin').toLowerCase();\n}\n\n/**\n * Upload a file to wspace-files-svc and return its id + a presigned URL. The\n * caller persists the id (e.g. via `hokCreateEpisode({ fileId })`); the URL is\n * used for an immediate preview / download link.\n */\nexport async function uploadFileToFiles(file: File, folderPath: string): Promise<UploadedFile> {\n // 1. Resolve (or create) the destination folder — File.folderId is a real FK.\n const folder = await filesFetch<{ ensureFolderByPath?: { id: string } | null }>(ENSURE_FOLDER, {\n path: folderPath,\n });\n const folderId = folder.ensureFolderByPath?.id;\n if (!folderId) {\n throw new Error('Could not resolve the upload folder.');\n }\n\n const mimeType = file.type || 'application/octet-stream';\n const fileSize = file.size;\n\n // 2. Open a presigned upload session.\n const initiated = await filesFetch<{\n initiateUpload?: { uploadUrl?: string | null; session: { id: string } } | null;\n }>(INITIATE_UPLOAD, {\n input: {\n fileName: file.name,\n extension: fileExtension(file.name, mimeType),\n fileSize,\n mimeType,\n folderId,\n },\n });\n const uploadUrl = initiated.initiateUpload?.uploadUrl;\n const sessionId = initiated.initiateUpload?.session.id;\n if (!uploadUrl || !sessionId) {\n throw new Error('The files service did not return an upload URL.');\n }\n\n // 3. PUT the bytes straight to storage using the presigned URL. Content-Type\n // must match what was signed at initiateUpload.\n const putResponse = await fetch(uploadUrl, {\n method: 'PUT',\n body: file,\n headers: { 'Content-Type': mimeType },\n });\n if (!putResponse.ok) {\n throw new Error(`Upload to storage failed (${putResponse.status}).`);\n }\n\n // 4. Finalize — creates the File record. fileSize must match initiateUpload.\n const completed = await filesFetch<{\n completeUpload?: { fileId: string; file: { id: string; name: string } } | null;\n }>(COMPLETE_UPLOAD, {\n input: { sessionId, fileSize, folderId },\n });\n const fileRecord = completed.completeUpload?.file;\n if (!fileRecord?.id) {\n throw new Error('The upload could not be finalized.');\n }\n\n // 5. Resolve a presigned URL for immediate preview/download (best-effort).\n let url = '';\n try {\n const urlData = await filesFetch<{ getFileDownloadUrl?: string | null }>(\n GET_FILE_DOWNLOAD_URL,\n {\n id: fileRecord.id,\n expiresIn: DOWNLOAD_URL_TTL_SECONDS,\n }\n );\n url = urlData.getFileDownloadUrl ?? '';\n } catch {\n url = '';\n }\n\n return { id: fileRecord.id, url, name: fileRecord.name };\n}\n\n/** Resolve a wspace-files-svc file id to a presigned download URL for display. */\nexport function useFileUrl(fileId?: string | null) {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: ['hookmovies', 'file-url', fileId ?? ''],\n enabled: Boolean(fileId),\n staleTime: 30 * 60 * 1000,\n retry: 1,\n queryFn: async () => {\n const response = await graphqlFetch<{ getFileDownloadUrl: string | null }>({\n gateway: 'workspace',\n baseUrl: apiGatewayUrl,\n workspaceToken: true,\n query: GET_FILE_DOWNLOAD_URL,\n variables: { id: fileId, expiresIn: DOWNLOAD_URL_TTL_SECONDS },\n });\n if (response.errors?.length) {\n throw new Error(response.errors[0]?.message ?? 'Could not resolve file URL');\n }\n return response.data?.getFileDownloadUrl ?? null;\n },\n });\n}\n"],"mappings":";;;;AA6BA,IAAM,IAA2B,OAEpB,IAAe;CAC1B,WAAW;CACX,UAAU;CACX;AASD,eAAe,EACb,GACA,GACgB;CAChB,IAAM,IAAW,MAAM,EAAoB;EACzC,SAAS;EACT;EACA;EACA,gBAAgB;EACjB,CAAC;AACF,KAAI,EAAS,QAAQ,OACnB,OAAU,MAAM,EAAS,OAAO,IAAI,WAAW,uBAAuB;AAExE,KAAI,CAAC,EAAS,KACZ,OAAU,MAAM,sCAAsC;AAExD,QAAO,EAAS;;AAGlB,IAAM,IAAgB,qGAMhB,IAAkB,4JASlB,IAAkB,2JASlB,IAAwB;AAM9B,SAAS,EAAc,GAAc,GAA0B;CAC7D,IAAM,IAAM,EAAK,YAAY,IAAI;AAGjC,QAFI,IAAM,MAAM,IAAM,EAAK,SAAS,IAAU,EAAK,MAAM,IAAM,EAAE,CAAC,aAAa,IAC9D,EAAS,MAAM,IAAI,CAAC,MACjB,OAAO,aAAa;;AAQ1C,eAAsB,EAAkB,GAAY,GAA2C;CAK7F,IAAM,KAHS,MAAM,EAA2D,GAAe,EAC7F,MAAM,GACP,CAAC,EACsB,oBAAoB;AAC5C,KAAI,CAAC,EACH,OAAU,MAAM,uCAAuC;CAGzD,IAAM,IAAW,EAAK,QAAQ,4BACxB,IAAW,EAAK,MAGhB,IAAY,MAAM,EAErB,GAAiB,EAClB,OAAO;EACL,UAAU,EAAK;EACf,WAAW,EAAc,EAAK,MAAM,EAAS;EAC7C;EACA;EACA;EACD,EACF,CAAC,EACI,IAAY,EAAU,gBAAgB,WACtC,IAAY,EAAU,gBAAgB,QAAQ;AACpD,KAAI,CAAC,KAAa,CAAC,EACjB,OAAU,MAAM,kDAAkD;CAKpE,IAAM,IAAc,MAAM,MAAM,GAAW;EACzC,QAAQ;EACR,MAAM;EACN,SAAS,EAAE,gBAAgB,GAAU;EACtC,CAAC;AACF,KAAI,CAAC,EAAY,GACf,OAAU,MAAM,6BAA6B,EAAY,OAAO,IAAI;CAStE,IAAM,KALY,MAAM,EAErB,GAAiB,EAClB,OAAO;EAAE;EAAW;EAAU;EAAU,EACzC,CAAC,EAC2B,gBAAgB;AAC7C,KAAI,CAAC,GAAY,GACf,OAAU,MAAM,qCAAqC;CAIvD,IAAI,IAAM;AACV,KAAI;AAQF,OAPgB,MAAM,EACpB,GACA;GACE,IAAI,EAAW;GACf,WAAW;GACZ,CACF,EACa,sBAAsB;SAC9B;AACN,MAAM;;AAGR,QAAO;EAAE,IAAI,EAAW;EAAI;EAAK,MAAM,EAAW;EAAM"}
1
+ {"version":3,"file":"useFiles.js","names":[],"sources":["../../../src/hookmovies/hooks/useFiles.ts"],"sourcesContent":["/**\n * File hooks — self-tapes & episode masters via wspace-files-svc (NO duplication).\n * @module hookmovies/hooks\n *\n * HookMovies never stores blobs. Episodes (master/mezzanine) and audition\n * self-tapes reference files owned by wspace-files-svc by id. Upload uses the\n * SAME proven `graphqlFetch` transport as every other read/write in this MFE\n * (the shell's workspace gateway + token), driving the wspace-files 3-step\n * presigned flow directly:\n * ensureFolderByPath -> initiateUpload -> HTTP PUT -> completeUpload\n * Display resolves a file id to a presigned URL via `getFileDownloadUrl`.\n *\n * NOTE: we deliberately do NOT use the Apollo-based `uploadBlobToFiles` /\n * `getWorkspaceClient()` helper here — this shell wires its data plane through\n * `graphqlFetch`, not a global Apollo client, so `getWorkspaceClient()` returns\n * an un-networked client and the upload silently no-ops. `graphqlFetch` is the\n * transport the whole MFE already uses successfully.\n */\n\nimport { useQuery } from '@tanstack/react-query';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\n\nimport { useHookMovies } from '../context';\n\n/**\n * Six hours. wspace-files-svc rejects any `expiresIn` above the S3 7-day cap\n * (604800s) with an INTERNAL_SERVER_ERROR, so we deliberately stay well under\n * it — these URLs back immediate preview/download, not durable references.\n */\nconst DOWNLOAD_URL_TTL_SECONDS = 21_600;\n\nexport const FILE_FOLDERS = {\n selfTapes: '/HookMovies/SelfTapes',\n episodes: '/HookMovies/Episodes',\n artwork: '/HookMovies/Artwork',\n masters: '/HookMovies/Masters',\n clips: '/HookMovies/Clips',\n} as const;\n\nexport interface UploadedFile {\n id: string;\n url: string;\n name: string;\n}\n\n/** Thin wrapper over the workspace gateway using the MFE's proven transport. */\nasync function filesFetch<TData>(\n query: string,\n variables: Record<string, unknown>\n): Promise<TData> {\n const response = await graphqlFetch<TData>({\n gateway: 'workspace',\n query,\n variables,\n workspaceToken: true,\n });\n if (response.errors?.length) {\n throw new Error(response.errors[0]?.message ?? 'Files request failed');\n }\n if (!response.data) {\n throw new Error('Files response did not include data');\n }\n return response.data;\n}\n\nconst ENSURE_FOLDER = `\n mutation HokEnsureFolder($path: String!) {\n ensureFolderByPath(path: $path) { id }\n }\n`;\n\nconst INITIATE_UPLOAD = `\n mutation HokInitiateUpload($input: InitiateUploadInput!) {\n initiateUpload(input: $input) {\n uploadUrl\n session { id }\n }\n }\n`;\n\nconst COMPLETE_UPLOAD = `\n mutation HokCompleteUpload($input: CompleteUploadInput!) {\n completeUpload(input: $input) {\n fileId\n file { id name }\n }\n }\n`;\n\nconst GET_FILE_DOWNLOAD_URL = `\n query HokGetFileDownloadUrl($id: ID!, $expiresIn: Int) {\n getFileDownloadUrl(id: $id, expiresIn: $expiresIn)\n }\n`;\n\nfunction fileExtension(name: string, mimeType: string): string {\n const dot = name.lastIndexOf('.');\n if (dot > -1 && dot < name.length - 1) return name.slice(dot + 1).toLowerCase();\n const fromMime = mimeType.split('/')[1];\n return (fromMime ?? 'bin').toLowerCase();\n}\n\n/**\n * Upload a file to wspace-files-svc and return its id + a presigned URL. The\n * caller persists the id (e.g. via `hokCreateEpisode({ fileId })`); the URL is\n * used for an immediate preview / download link.\n */\nexport async function uploadFileToFiles(file: File, folderPath: string): Promise<UploadedFile> {\n // 1. Resolve (or create) the destination folder — File.folderId is a real FK.\n const folder = await filesFetch<{ ensureFolderByPath?: { id: string } | null }>(ENSURE_FOLDER, {\n path: folderPath,\n });\n const folderId = folder.ensureFolderByPath?.id;\n if (!folderId) {\n throw new Error('Could not resolve the upload folder.');\n }\n\n const mimeType = file.type || 'application/octet-stream';\n const fileSize = file.size;\n\n // 2. Open a presigned upload session.\n const initiated = await filesFetch<{\n initiateUpload?: { uploadUrl?: string | null; session: { id: string } } | null;\n }>(INITIATE_UPLOAD, {\n input: {\n fileName: file.name,\n extension: fileExtension(file.name, mimeType),\n fileSize,\n mimeType,\n folderId,\n },\n });\n const uploadUrl = initiated.initiateUpload?.uploadUrl;\n const sessionId = initiated.initiateUpload?.session.id;\n if (!uploadUrl || !sessionId) {\n throw new Error('The files service did not return an upload URL.');\n }\n\n // 3. PUT the bytes straight to storage using the presigned URL. Content-Type\n // must match what was signed at initiateUpload.\n const putResponse = await fetch(uploadUrl, {\n method: 'PUT',\n body: file,\n headers: { 'Content-Type': mimeType },\n });\n if (!putResponse.ok) {\n throw new Error(`Upload to storage failed (${putResponse.status}).`);\n }\n\n // 4. Finalize — creates the File record. fileSize must match initiateUpload.\n const completed = await filesFetch<{\n completeUpload?: { fileId: string; file: { id: string; name: string } } | null;\n }>(COMPLETE_UPLOAD, {\n input: { sessionId, fileSize, folderId },\n });\n const fileRecord = completed.completeUpload?.file;\n if (!fileRecord?.id) {\n throw new Error('The upload could not be finalized.');\n }\n\n // 5. Resolve a presigned URL for immediate preview/download (best-effort).\n let url = '';\n try {\n const urlData = await filesFetch<{ getFileDownloadUrl?: string | null }>(\n GET_FILE_DOWNLOAD_URL,\n {\n id: fileRecord.id,\n expiresIn: DOWNLOAD_URL_TTL_SECONDS,\n }\n );\n url = urlData.getFileDownloadUrl ?? '';\n } catch {\n url = '';\n }\n\n return { id: fileRecord.id, url, name: fileRecord.name };\n}\n\n/** Resolve a wspace-files-svc file id to a presigned download URL for display. */\nexport function useFileUrl(fileId?: string | null) {\n const { apiGatewayUrl } = useHookMovies();\n return useQuery({\n queryKey: ['hookmovies', 'file-url', fileId ?? ''],\n enabled: Boolean(fileId),\n staleTime: 30 * 60 * 1000,\n retry: 1,\n queryFn: async () => {\n const response = await graphqlFetch<{ getFileDownloadUrl: string | null }>({\n gateway: 'workspace',\n baseUrl: apiGatewayUrl,\n workspaceToken: true,\n query: GET_FILE_DOWNLOAD_URL,\n variables: { id: fileId, expiresIn: DOWNLOAD_URL_TTL_SECONDS },\n });\n if (response.errors?.length) {\n throw new Error(response.errors[0]?.message ?? 'Could not resolve file URL');\n }\n return response.data?.getFileDownloadUrl ?? null;\n },\n });\n}\n"],"mappings":";;;;;AA6BA,IAAM,IAA2B,OAEpB,IAAe;CAC1B,WAAW;CACX,UAAU;CACV,SAAS;CACT,SAAS;CACT,OAAO;CACR;AASD,eAAe,EACb,GACA,GACgB;CAChB,IAAM,IAAW,MAAM,EAAoB;EACzC,SAAS;EACT;EACA;EACA,gBAAgB;EACjB,CAAC;AACF,KAAI,EAAS,QAAQ,OACnB,OAAU,MAAM,EAAS,OAAO,IAAI,WAAW,uBAAuB;AAExE,KAAI,CAAC,EAAS,KACZ,OAAU,MAAM,sCAAsC;AAExD,QAAO,EAAS;;AAGlB,IAAM,IAAgB,qGAMhB,IAAkB,4JASlB,IAAkB,2JASlB,IAAwB;AAM9B,SAAS,EAAc,GAAc,GAA0B;CAC7D,IAAM,IAAM,EAAK,YAAY,IAAI;AAGjC,QAFI,IAAM,MAAM,IAAM,EAAK,SAAS,IAAU,EAAK,MAAM,IAAM,EAAE,CAAC,aAAa,IAC9D,EAAS,MAAM,IAAI,CAAC,MACjB,OAAO,aAAa;;AAQ1C,eAAsB,EAAkB,GAAY,GAA2C;CAK7F,IAAM,KAHS,MAAM,EAA2D,GAAe,EAC7F,MAAM,GACP,CAAC,EACsB,oBAAoB;AAC5C,KAAI,CAAC,EACH,OAAU,MAAM,uCAAuC;CAGzD,IAAM,IAAW,EAAK,QAAQ,4BACxB,IAAW,EAAK,MAGhB,IAAY,MAAM,EAErB,GAAiB,EAClB,OAAO;EACL,UAAU,EAAK;EACf,WAAW,EAAc,EAAK,MAAM,EAAS;EAC7C;EACA;EACA;EACD,EACF,CAAC,EACI,IAAY,EAAU,gBAAgB,WACtC,IAAY,EAAU,gBAAgB,QAAQ;AACpD,KAAI,CAAC,KAAa,CAAC,EACjB,OAAU,MAAM,kDAAkD;CAKpE,IAAM,IAAc,MAAM,MAAM,GAAW;EACzC,QAAQ;EACR,MAAM;EACN,SAAS,EAAE,gBAAgB,GAAU;EACtC,CAAC;AACF,KAAI,CAAC,EAAY,GACf,OAAU,MAAM,6BAA6B,EAAY,OAAO,IAAI;CAStE,IAAM,KALY,MAAM,EAErB,GAAiB,EAClB,OAAO;EAAE;EAAW;EAAU;EAAU,EACzC,CAAC,EAC2B,gBAAgB;AAC7C,KAAI,CAAC,GAAY,GACf,OAAU,MAAM,qCAAqC;CAIvD,IAAI,IAAM;AACV,KAAI;AAQF,OAPgB,MAAM,EACpB,GACA;GACE,IAAI,EAAW;GACf,WAAW;GACZ,CACF,EACa,sBAAsB;SAC9B;AACN,MAAM;;AAGR,QAAO;EAAE,IAAI,EAAW;EAAI;EAAK,MAAM,EAAW;EAAM;;AAI1D,SAAgB,EAAW,GAAwB;CACjD,IAAM,EAAE,qBAAkB,GAAe;AACzC,QAAO,EAAS;EACd,UAAU;GAAC;GAAc;GAAY,KAAU;GAAG;EAClD,SAAS,EAAQ;EACjB,WAAW,OAAU;EACrB,OAAO;EACP,SAAS,YAAY;GACnB,IAAM,IAAW,MAAM,EAAoD;IACzE,SAAS;IACT,SAAS;IACT,gBAAgB;IAChB,OAAO;IACP,WAAW;KAAE,IAAI;KAAQ,WAAW;KAA0B;IAC/D,CAAC;AACF,OAAI,EAAS,QAAQ,OACnB,OAAU,MAAM,EAAS,OAAO,IAAI,WAAW,6BAA6B;AAE9E,UAAO,EAAS,MAAM,sBAAsB;;EAE/C,CAAC"}