@fluid-app/portal-sdk 0.1.131 → 0.1.133

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 (146) hide show
  1. package/dist/{AlertWidget-WQ_XPDRo.mjs → AlertWidget-BYbcGyNr.mjs} +3 -3
  2. package/dist/{AlertWidget-WQ_XPDRo.mjs.map → AlertWidget-BYbcGyNr.mjs.map} +1 -1
  3. package/dist/{AppDownloadScreen-zNP4k8ht.cjs → AppDownloadScreen-B-i6Rydi.cjs} +1 -1
  4. package/dist/{AppDownloadScreen-BOfG3cqC.mjs → AppDownloadScreen-BpExiJat.mjs} +3 -3
  5. package/dist/{AppDownloadScreen-BOfG3cqC.mjs.map → AppDownloadScreen-BpExiJat.mjs.map} +1 -1
  6. package/dist/{AppDownloadScreen-BjCtTMPU.cjs → AppDownloadScreen-CIqSvpV0.cjs} +1 -1
  7. package/dist/{AppDownloadScreen-BjCtTMPU.cjs.map → AppDownloadScreen-CIqSvpV0.cjs.map} +1 -1
  8. package/dist/{BulletListWidget-BYcaQnVH.mjs → BulletListWidget-Bo5Kj1W-.mjs} +2 -2
  9. package/dist/{BulletListWidget-BYcaQnVH.mjs.map → BulletListWidget-Bo5Kj1W-.mjs.map} +1 -1
  10. package/dist/{CalendarWidget-Qb-utCFD.mjs → CalendarWidget-CCsceh_0.mjs} +2 -2
  11. package/dist/{CalendarWidget-Qb-utCFD.mjs.map → CalendarWidget-CCsceh_0.mjs.map} +1 -1
  12. package/dist/{CardWidget-zVxobZDH.mjs → CardWidget-BkOMSBQ-.mjs} +2 -2
  13. package/dist/{CardWidget-zVxobZDH.mjs.map → CardWidget-BkOMSBQ-.mjs.map} +1 -1
  14. package/dist/{CarouselWidget-dpRCljEx.mjs → CarouselWidget-B9LsTYUF.mjs} +2 -2
  15. package/dist/{CarouselWidget-dpRCljEx.mjs.map → CarouselWidget-B9LsTYUF.mjs.map} +1 -1
  16. package/dist/{CatchUpWidget-CSIXsR82.mjs → CatchUpWidget-CSJdJgs-.mjs} +2 -2
  17. package/dist/{CatchUpWidget-CSIXsR82.mjs.map → CatchUpWidget-CSJdJgs-.mjs.map} +1 -1
  18. package/dist/{ChartWidget-88hpX7ft.mjs → ChartWidget-Cpzqi6W4.mjs} +2 -2
  19. package/dist/{ChartWidget-88hpX7ft.mjs.map → ChartWidget-Cpzqi6W4.mjs.map} +1 -1
  20. package/dist/{ContactsScreen-BvoMicyB.mjs → ContactsScreen-BRmYDosJ.mjs} +5 -5
  21. package/dist/{ContactsScreen-BvoMicyB.mjs.map → ContactsScreen-BRmYDosJ.mjs.map} +1 -1
  22. package/dist/{ContainerWidget-DNS7ynby.mjs → ContainerWidget-DTchKDKw.mjs} +3 -3
  23. package/dist/{ContainerWidget-DNS7ynby.mjs.map → ContainerWidget-DTchKDKw.mjs.map} +1 -1
  24. package/dist/{CustomersScreen-xAauAB-B.mjs → CustomersScreen-Cnn-Wcza.mjs} +2 -2
  25. package/dist/{CustomersScreen-xAauAB-B.mjs.map → CustomersScreen-Cnn-Wcza.mjs.map} +1 -1
  26. package/dist/{EmbedWidget-BQYixJLj.mjs → EmbedWidget-Du9DMpSo.mjs} +2 -2
  27. package/dist/{EmbedWidget-BQYixJLj.mjs.map → EmbedWidget-Du9DMpSo.mjs.map} +1 -1
  28. package/dist/{FluidProvider-B-f_JVal.mjs → FluidProvider-BUdNsR8f.mjs} +49 -49
  29. package/dist/{FluidProvider-B-f_JVal.mjs.map → FluidProvider-BUdNsR8f.mjs.map} +1 -1
  30. package/dist/FluidProvider-CQoQjYxU.cjs.map +1 -1
  31. package/dist/{ImageWidget-DE9Fp_oH.mjs → ImageWidget-B1Mx3qKN.mjs} +2 -2
  32. package/dist/{ImageWidget-DE9Fp_oH.mjs.map → ImageWidget-B1Mx3qKN.mjs.map} +1 -1
  33. package/dist/{LayoutWidget-BFO_PHWw.mjs → LayoutWidget-Bgodl7eR.mjs} +2 -2
  34. package/dist/{LayoutWidget-BFO_PHWw.mjs.map → LayoutWidget-Bgodl7eR.mjs.map} +1 -1
  35. package/dist/{LinkWidget-JSoDi-ag.mjs → LinkWidget-B5PlWJHe.mjs} +2 -2
  36. package/dist/{LinkWidget-JSoDi-ag.mjs.map → LinkWidget-B5PlWJHe.mjs.map} +1 -1
  37. package/dist/{ListWidget-CBLZ8CjD.mjs → ListWidget-BWfsmVoc.mjs} +2 -2
  38. package/dist/{ListWidget-CBLZ8CjD.mjs.map → ListWidget-BWfsmVoc.mjs.map} +1 -1
  39. package/dist/{MessagingScreen-COWASb0E.mjs → MessagingScreen-CQwR5WA1.mjs} +9 -6
  40. package/dist/{MessagingScreen-COWASb0E.mjs.map → MessagingScreen-CQwR5WA1.mjs.map} +1 -1
  41. package/dist/{MySiteScreen-BasZFpx7.cjs → MySiteScreen-C00HjZdl.cjs} +1 -1
  42. package/dist/{MySiteScreen-B5-bV1-O.mjs → MySiteScreen-CcxWz0IH.mjs} +4 -4
  43. package/dist/{MySiteScreen-B5-bV1-O.mjs.map → MySiteScreen-CcxWz0IH.mjs.map} +1 -1
  44. package/dist/{MySiteScreen-DURa034X.cjs → MySiteScreen-D56qESn0.cjs} +1 -1
  45. package/dist/{MySiteScreen-DURa034X.cjs.map → MySiteScreen-D56qESn0.cjs.map} +1 -1
  46. package/dist/{MySiteWidget-BqtLSExC.mjs → MySiteWidget-mK0Mj3DS.mjs} +2 -2
  47. package/dist/{MySiteWidget-BqtLSExC.mjs.map → MySiteWidget-mK0Mj3DS.mjs.map} +1 -1
  48. package/dist/{NestedWidget-DIwW-wM7.mjs → NestedWidget-B6cUOyI3.mjs} +2 -2
  49. package/dist/{NestedWidget-DIwW-wM7.mjs.map → NestedWidget-B6cUOyI3.mjs.map} +1 -1
  50. package/dist/{OrdersScreen-BcFvAtJ_.mjs → OrdersScreen-CpOywVHJ.mjs} +4 -4
  51. package/dist/{OrdersScreen-BcFvAtJ_.mjs.map → OrdersScreen-CpOywVHJ.mjs.map} +1 -1
  52. package/dist/{PointsWidget-DgLGU995.mjs → PointsWidget-BlEzqgbK.mjs} +2 -2
  53. package/dist/{PointsWidget-DgLGU995.mjs.map → PointsWidget-BlEzqgbK.mjs.map} +1 -1
  54. package/dist/{ProductsScreen-Mu8doz5F.cjs → ProductsScreen-BPNdpsYm.cjs} +2 -2
  55. package/dist/{src-CMByt6YP.cjs → ProductsScreen-BY285fh-.cjs} +90 -31
  56. package/dist/ProductsScreen-BY285fh-.cjs.map +1 -0
  57. package/dist/ProductsScreen-DMldTDPg.mjs +42 -0
  58. package/dist/{src-DryOJTBW.mjs → ProductsScreen-jdy2j9_J.mjs} +86 -28
  59. package/dist/ProductsScreen-jdy2j9_J.mjs.map +1 -0
  60. package/dist/{ProfileScreen-CnQqdYBE.mjs → ProfileScreen-mAUuAFhe.mjs} +5 -5
  61. package/dist/{ProfileScreen-CnQqdYBE.mjs.map → ProfileScreen-mAUuAFhe.mjs.map} +1 -1
  62. package/dist/{QuickShareWidget-CajKauDa.mjs → QuickShareWidget-Lpox79Cq.mjs} +2 -2
  63. package/dist/{QuickShareWidget-CajKauDa.mjs.map → QuickShareWidget-Lpox79Cq.mjs.map} +1 -1
  64. package/dist/{RecentActivityWidget-BZYB21eR.mjs → RecentActivityWidget-BdPmAQq4.mjs} +2 -2
  65. package/dist/{RecentActivityWidget-BZYB21eR.mjs.map → RecentActivityWidget-BdPmAQq4.mjs.map} +1 -1
  66. package/dist/{SeparatorWidget-Lsd6juu7.mjs → SeparatorWidget-BS966Lk4.mjs} +2 -2
  67. package/dist/{SeparatorWidget-Lsd6juu7.mjs.map → SeparatorWidget-BS966Lk4.mjs.map} +1 -1
  68. package/dist/ShareablesScreen-B6tMQzuX.mjs +1314 -0
  69. package/dist/ShareablesScreen-B6tMQzuX.mjs.map +1 -0
  70. package/dist/{ShareablesScreen-oZhW2jGu.cjs → ShareablesScreen-DMBXIMMj.cjs} +2 -2
  71. package/dist/ShareablesScreen-d_ThfnNQ.mjs +42 -0
  72. package/dist/ShareablesScreen-znVUD_OK.cjs +1332 -0
  73. package/dist/ShareablesScreen-znVUD_OK.cjs.map +1 -0
  74. package/dist/{ShopScreen-B1UzSmK8.cjs → ShopScreen-BVIT_QS-.cjs} +6 -4
  75. package/dist/ShopScreen-BVIT_QS-.cjs.map +1 -0
  76. package/dist/{ShopScreen-7HWz_B6R.cjs → ShopScreen-Bsjdn-E9.cjs} +1 -1
  77. package/dist/{ShopScreen-D1N3RWm9.mjs → ShopScreen-C1bnhxpj.mjs} +9 -7
  78. package/dist/ShopScreen-C1bnhxpj.mjs.map +1 -0
  79. package/dist/{SpacerWidget-B3zkEePP.mjs → SpacerWidget-BimE1fjJ.mjs} +2 -2
  80. package/dist/{SpacerWidget-B3zkEePP.mjs.map → SpacerWidget-BimE1fjJ.mjs.map} +1 -1
  81. package/dist/{SubscriptionsScreen-Bw3xkq7t.mjs → SubscriptionsScreen-QHf54yD7.mjs} +5 -5
  82. package/dist/{SubscriptionsScreen-Bw3xkq7t.mjs.map → SubscriptionsScreen-QHf54yD7.mjs.map} +1 -1
  83. package/dist/{TableWidget-Xz0d4UH5.mjs → TableWidget-CfSqeNQj.mjs} +2 -2
  84. package/dist/{TableWidget-Xz0d4UH5.mjs.map → TableWidget-CfSqeNQj.mjs.map} +1 -1
  85. package/dist/{TextWidget-CzUlNmCl.mjs → TextWidget-DYpbUtQh.mjs} +2 -2
  86. package/dist/{TextWidget-CzUlNmCl.mjs.map → TextWidget-DYpbUtQh.mjs.map} +1 -1
  87. package/dist/{ToDoWidget-qyFLHU_o.mjs → ToDoWidget-DaxkgCEl.mjs} +2 -2
  88. package/dist/{ToDoWidget-qyFLHU_o.mjs.map → ToDoWidget-DaxkgCEl.mjs.map} +1 -1
  89. package/dist/{UpgradeScreen-CIiEjeTZ.cjs → UpgradeScreen--eiiE1rX.cjs} +1 -1
  90. package/dist/{UpgradeScreen-IaYxGm7M.cjs → UpgradeScreen-7on9GOgu.cjs} +1 -1
  91. package/dist/{UpgradeScreen-IaYxGm7M.cjs.map → UpgradeScreen-7on9GOgu.cjs.map} +1 -1
  92. package/dist/{UpgradeScreen-BZdJQxb9.mjs → UpgradeScreen-p7aAXWFM.mjs} +2 -2
  93. package/dist/{UpgradeScreen-BZdJQxb9.mjs.map → UpgradeScreen-p7aAXWFM.mjs.map} +1 -1
  94. package/dist/{VideoWidget-CpUPsOI7.mjs → VideoWidget-CHktk3hs.mjs} +2 -2
  95. package/dist/{VideoWidget-CpUPsOI7.mjs.map → VideoWidget-CHktk3hs.mjs.map} +1 -1
  96. package/dist/{dist-B1HwSrso.mjs → dist-CayuD99K.mjs} +1 -1
  97. package/dist/{dist-B1HwSrso.mjs.map → dist-CayuD99K.mjs.map} +1 -1
  98. package/dist/{es-BcjHf1ZX.mjs → es-CTLNkiWp.mjs} +38 -3
  99. package/dist/{es-BcjHf1ZX.mjs.map → es-CTLNkiWp.mjs.map} +1 -1
  100. package/dist/index.cjs +19 -19
  101. package/dist/index.d.cts.map +1 -1
  102. package/dist/index.d.mts.map +1 -1
  103. package/dist/index.mjs +70 -70
  104. package/dist/index.mjs.map +1 -1
  105. package/dist/{order-status-badge-OZ1InBwZ.mjs → order-status-badge-Bt2gMEPZ.mjs} +1 -1
  106. package/dist/{order-status-badge-OZ1InBwZ.mjs.map → order-status-badge-Bt2gMEPZ.mjs.map} +1 -1
  107. package/dist/{sortable.esm-DSrWP4x9.mjs → sortable.esm-BzPsVjTI.mjs} +1 -1
  108. package/dist/{sortable.esm-DSrWP4x9.mjs.map → sortable.esm-BzPsVjTI.mjs.map} +1 -1
  109. package/dist/{src-DIcd2_ex.cjs → src-C5GUPE_i.cjs} +37 -26
  110. package/dist/src-C5GUPE_i.cjs.map +1 -0
  111. package/dist/{src-k03GJfKt.mjs → src-DcIV4Mpe.mjs} +41 -30
  112. package/dist/src-DcIV4Mpe.mjs.map +1 -0
  113. package/dist/{use-account-clients-CZw8FqxD.mjs → use-account-clients-BjK5QVYl.mjs} +2 -2
  114. package/dist/{use-account-clients-CZw8FqxD.mjs.map → use-account-clients-BjK5QVYl.mjs.map} +1 -1
  115. package/dist/{use-current-user-C6af9r0B.mjs → use-current-user-BP_GJuQe.mjs} +3 -3
  116. package/dist/{use-current-user-C6af9r0B.mjs.map → use-current-user-BP_GJuQe.mjs.map} +1 -1
  117. package/dist/{use-fluid-api-R0Qybt_F.mjs → use-fluid-api-UtVBk6E-.mjs} +2 -2
  118. package/dist/{use-fluid-api-R0Qybt_F.mjs.map → use-fluid-api-UtVBk6E-.mjs.map} +1 -1
  119. package/dist/{use-fluid-auth-_pnjCu2c.mjs → use-fluid-auth-DrPeCmW-.mjs} +2 -2
  120. package/dist/{use-fluid-auth-_pnjCu2c.mjs.map → use-fluid-auth-DrPeCmW-.mjs.map} +1 -1
  121. package/dist/{use-portal-products-client-Bl-yd0Tl.cjs → use-portal-products-client-CIrRGIxC.cjs} +5 -14
  122. package/dist/use-portal-products-client-CIrRGIxC.cjs.map +1 -0
  123. package/dist/{use-portal-products-client-tJi4q54S.mjs → use-portal-products-client-dV5jIXpp.mjs} +6 -15
  124. package/dist/use-portal-products-client-dV5jIXpp.mjs.map +1 -0
  125. package/package.json +18 -18
  126. package/dist/MessagingScreen-CWm4iQnk.mjs +0 -38
  127. package/dist/ProductsScreen-BHeRiKUM.cjs +0 -101
  128. package/dist/ProductsScreen-BHeRiKUM.cjs.map +0 -1
  129. package/dist/ProductsScreen-C_1ghW3w.mjs +0 -42
  130. package/dist/ProductsScreen-DJOPzE9v.mjs +0 -89
  131. package/dist/ProductsScreen-DJOPzE9v.mjs.map +0 -1
  132. package/dist/ShareablesScreen-BSRbPf6u.cjs +0 -414
  133. package/dist/ShareablesScreen-BSRbPf6u.cjs.map +0 -1
  134. package/dist/ShareablesScreen-COyBtpDy.mjs +0 -42
  135. package/dist/ShareablesScreen-kBJFUklJ.mjs +0 -396
  136. package/dist/ShareablesScreen-kBJFUklJ.mjs.map +0 -1
  137. package/dist/ShopScreen-B1UzSmK8.cjs.map +0 -1
  138. package/dist/ShopScreen-D1N3RWm9.mjs.map +0 -1
  139. package/dist/chunk-ByhMGyNw.mjs +0 -37
  140. package/dist/src-CMByt6YP.cjs.map +0 -1
  141. package/dist/src-DIcd2_ex.cjs.map +0 -1
  142. package/dist/src-DryOJTBW.mjs.map +0 -1
  143. package/dist/src-k03GJfKt.mjs.map +0 -1
  144. package/dist/use-portal-products-client-Bl-yd0Tl.cjs.map +0 -1
  145. package/dist/use-portal-products-client-tJi4q54S.mjs.map +0 -1
  146. /package/dist/{src-DAC9DwXZ.mjs → src-6SxtfYk9.mjs} +0 -0
@@ -0,0 +1,1314 @@
1
+ import { et as USER_TYPES, u as usePortalTenantClient } from "./FluidProvider-BUdNsR8f.mjs";
2
+ import { t as useFluidAuth } from "./use-fluid-auth-DrPeCmW-.mjs";
3
+ import { n as useCurrentUser } from "./use-current-user-BP_GJuQe.mjs";
4
+ import { n as useAppNavigation } from "./AppNavigationContext-Du3Qq0yc.mjs";
5
+ import { i as useSdkClient } from "./use-account-clients-BjK5QVYl.mjs";
6
+ import { a as ShareablesApiProvider, i as ShareablesUIProvider, n as ShareablesApp, o as ShareablesCoreProvider, r as getFileMimeType } from "./src-DcIV4Mpe.mjs";
7
+ import { t as usePortalProductsClient } from "./use-portal-products-client-dV5jIXpp.mjs";
8
+ import { useCallback, useMemo } from "react";
9
+ import { jsx } from "react/jsx-runtime";
10
+ import { z } from "zod";
11
+ //#region src/hooks/use-user-type.ts
12
+ /**
13
+ * Convenience hook for user-type checks in the portal SDK.
14
+ */
15
+ function useUserType() {
16
+ const { user } = useFluidAuth();
17
+ return useMemo(() => {
18
+ const userType = user?.user_type ?? null;
19
+ return {
20
+ userType,
21
+ isCustomer: userType === USER_TYPES.customer,
22
+ isRep: userType === USER_TYPES.rep,
23
+ isAdmin: userType === USER_TYPES.admin || userType === USER_TYPES.root_admin
24
+ };
25
+ }, [user?.user_type]);
26
+ }
27
+ //#endregion
28
+ //#region ../../file-picker/core/src/schemas/dam.ts
29
+ const damVariantSchema = z.object({
30
+ id: z.string(),
31
+ url: z.string().nullable(),
32
+ file_name: z.string(),
33
+ mime_type: z.string(),
34
+ content: z.any().nullable(),
35
+ created_at: z.string(),
36
+ updated_at: z.string(),
37
+ default: z.boolean(),
38
+ is_original: z.boolean(),
39
+ is_text: z.boolean(),
40
+ media_type: z.string(),
41
+ processing_status: z.string(),
42
+ tags: z.array(z.string())
43
+ });
44
+ const damAssetSchema = z.object({
45
+ id: z.number(),
46
+ canonical_path: z.string(),
47
+ category: z.string(),
48
+ code: z.string(),
49
+ company: z.string(),
50
+ created_at: z.string(),
51
+ default_variant_id: z.string(),
52
+ default_variant_url: z.string().optional(),
53
+ description: z.string(),
54
+ name: z.string(),
55
+ updated_at: z.string(),
56
+ variants: z.array(damVariantSchema).optional()
57
+ });
58
+ const damTreeFolderNodeSchema = z.object({
59
+ asset_code: z.union([z.string(), z.record(z.string(), z.unknown())]).optional(),
60
+ name: z.union([z.string(), z.record(z.string(), z.unknown())]).optional(),
61
+ category: z.union([z.string(), z.record(z.string(), z.unknown())]).optional(),
62
+ variants: z.union([z.array(z.unknown()), z.record(z.string(), z.unknown())]).optional()
63
+ }).passthrough();
64
+ const damTreeSchema = z.record(z.string(), z.union([
65
+ z.lazy(() => damTreeSchema),
66
+ damAssetSchema,
67
+ damTreeFolderNodeSchema
68
+ ]));
69
+ const damQueryResponseSchema = z.object({
70
+ path: z.string(),
71
+ tree: damTreeSchema,
72
+ meta: z.object({ next_cursor: z.string().optional() }).optional()
73
+ });
74
+ z.object({ asset: z.object({
75
+ file: z.any(),
76
+ name: z.string(),
77
+ description: z.string().optional(),
78
+ tags: z.string().optional()
79
+ }) });
80
+ const damAssetCreateResponseSchema = z.object({
81
+ asset: damAssetSchema,
82
+ meta: z.object({
83
+ request_id: z.string(),
84
+ timestamp: z.string()
85
+ })
86
+ });
87
+ z.object({
88
+ placeholder_asset: z.object({
89
+ mime_type: z.string(),
90
+ name: z.string().optional(),
91
+ description: z.string().optional()
92
+ }),
93
+ skip_autotagging: z.boolean().optional()
94
+ });
95
+ z.object({
96
+ asset: z.object({
97
+ file: z.any(),
98
+ name: z.string(),
99
+ description: z.string().optional(),
100
+ tags: z.string().optional()
101
+ }).optional(),
102
+ text_asset: z.object({
103
+ file_name: z.string(),
104
+ mime_type: z.string(),
105
+ text: z.string(),
106
+ name: z.string().optional(),
107
+ description: z.string().optional(),
108
+ tags: z.string().optional()
109
+ }).optional(),
110
+ placeholder_asset: z.object({
111
+ mime_type: z.string(),
112
+ name: z.string().optional(),
113
+ description: z.string().optional()
114
+ }).optional(),
115
+ skip_autotagging: z.boolean().optional()
116
+ });
117
+ const damAssetPathCreateResponseSchema = z.object({
118
+ asset: z.object({
119
+ id: z.number(),
120
+ canonical_path: z.string(),
121
+ name: z.string()
122
+ }),
123
+ meta: z.object({
124
+ request_id: z.string(),
125
+ timestamp: z.string()
126
+ })
127
+ });
128
+ //#endregion
129
+ //#region ../../api-clients/portal-tenant-content/src/namespaces/portal_tenant_content.ts
130
+ /**
131
+ * List media (own uploads and company media)
132
+ * Returns a paginated list of the member's own uploads and company-owned media.
133
+ *
134
+ * @param client - Fetch client instance
135
+ * @param [params] - params
136
+ */
137
+ async function media_list(client, params) {
138
+ return client.get(`/api/content/media`, params);
139
+ }
140
+ /**
141
+ * Create a new media item
142
+ * Creates a new media item record.
143
+ *
144
+ * @param client - Fetch client instance
145
+ * @param body - body
146
+ */
147
+ async function media_create(client, body) {
148
+ return client.post(`/api/content/media`, body);
149
+ }
150
+ /**
151
+ * Get a specific media item
152
+ * Returns a single media item by ID.
153
+ *
154
+ * @param client - Fetch client instance
155
+ * @param id - id
156
+ */
157
+ async function media_show(client, id) {
158
+ return client.get(`/api/content/media/${id}`);
159
+ }
160
+ /**
161
+ * Update a media item (own uploads only)
162
+ * Updates a media item's title or description.
163
+ *
164
+ * @param client - Fetch client instance
165
+ * @param id - id
166
+ * @param body - body
167
+ */
168
+ async function media_update(client, id, body) {
169
+ return client.patch(`/api/content/media/${id}`, body);
170
+ }
171
+ /**
172
+ * Delete a media item (own uploads only)
173
+ * Removes a media item.
174
+ *
175
+ * @param client - Fetch client instance
176
+ * @param id - id
177
+ */
178
+ async function media_destroy(client, id) {
179
+ return client.delete(`/api/content/media/${id}`);
180
+ }
181
+ /**
182
+ * List playlists with cursor pagination
183
+ * Returns a paginated list of playlists.
184
+ *
185
+ * @param client - Fetch client instance
186
+ * @param [params] - params
187
+ */
188
+ async function playlists_list(client, params) {
189
+ return client.get(`/api/content/playlists`, params);
190
+ }
191
+ /**
192
+ * Create a new playlist
193
+ * Creates a new playlist.
194
+ *
195
+ * @param client - Fetch client instance
196
+ * @param body - body
197
+ */
198
+ async function playlists_create(client, body) {
199
+ return client.post(`/api/content/playlists`, body);
200
+ }
201
+ /**
202
+ * Get a specific playlist
203
+ * Returns a single playlist by ID.
204
+ *
205
+ * @param client - Fetch client instance
206
+ * @param id - id
207
+ */
208
+ async function playlists_show(client, id) {
209
+ return client.get(`/api/content/playlists/${id}`);
210
+ }
211
+ /**
212
+ * Update a playlist
213
+ * Updates a playlist's title or metadata.
214
+ *
215
+ * @param client - Fetch client instance
216
+ * @param id - id
217
+ * @param body - body
218
+ */
219
+ async function playlists_update(client, id, body) {
220
+ return client.patch(`/api/content/playlists/${id}`, body);
221
+ }
222
+ /**
223
+ * Delete a playlist
224
+ * Removes a playlist.
225
+ *
226
+ * @param client - Fetch client instance
227
+ * @param id - id
228
+ */
229
+ async function playlists_destroy(client, id) {
230
+ return client.delete(`/api/content/playlists/${id}`);
231
+ }
232
+ /**
233
+ * List items in a playlist
234
+ * Returns a paginated list of items in a playlist.
235
+ *
236
+ * @param client - Fetch client instance
237
+ * @param playlist_id - playlist_id
238
+ * @param [params] - params
239
+ */
240
+ async function playlists_items_list(client, playlist_id, params) {
241
+ return client.get(`/api/content/playlists/${playlist_id}/items`, params);
242
+ }
243
+ /**
244
+ * Add an item to a playlist
245
+ * Adds a media item to a playlist.
246
+ *
247
+ * @param client - Fetch client instance
248
+ * @param playlist_id - playlist_id
249
+ * @param body - body
250
+ */
251
+ async function playlists_items_add(client, playlist_id, body) {
252
+ return client.post(`/api/content/playlists/${playlist_id}/items`, body);
253
+ }
254
+ /**
255
+ * Remove an item from a playlist
256
+ * Removes a single item from a playlist.
257
+ *
258
+ * @param client - Fetch client instance
259
+ * @param playlist_id - playlist_id
260
+ * @param id - id
261
+ */
262
+ async function playlists_items_remove(client, playlist_id, id) {
263
+ return client.delete(`/api/content/playlists/${playlist_id}/items/${id}`);
264
+ }
265
+ /**
266
+ * List share links for the current user
267
+ * Returns a paginated list of share links.
268
+ *
269
+ * @param client - Fetch client instance
270
+ * @param [params] - params
271
+ */
272
+ async function shares_list(client, params) {
273
+ return client.get(`/api/shares`, params);
274
+ }
275
+ /**
276
+ * Create a share link
277
+ * Creates a new share link for content.
278
+ *
279
+ * @param client - Fetch client instance
280
+ * @param body - body
281
+ */
282
+ async function shares_create(client, body) {
283
+ return client.post(`/api/shares`, body);
284
+ }
285
+ /**
286
+ * List DAM assets
287
+ * Returns a paginated list of DAM assets for the company.
288
+ *
289
+ * @param client - Fetch client instance
290
+ * @param [params] - params
291
+ */
292
+ async function dam_assets_list(client, params) {
293
+ return client.get(`/api/content/dam/assets`, params);
294
+ }
295
+ /**
296
+ * Create a DAM asset placeholder
297
+ * Creates a new DAM asset placeholder record with a canonical path.
298
+ *
299
+ * @param client - Fetch client instance
300
+ * @param body - body
301
+ */
302
+ async function dam_assets_create(client, body) {
303
+ return client.post(`/api/content/dam/assets`, body);
304
+ }
305
+ /**
306
+ * List paths for a DAM asset
307
+ * Returns a paginated list of path aliases for a DAM asset.
308
+ *
309
+ * @param client - Fetch client instance
310
+ * @param asset_code - asset_code
311
+ * @param [params] - params
312
+ */
313
+ async function dam_asset_paths_list(client, asset_code, params) {
314
+ return client.get(`/api/content/dam/assets/${asset_code}/paths`, params);
315
+ }
316
+ /**
317
+ * Create a path alias for a DAM asset
318
+ * Creates a new path alias for an existing DAM asset.
319
+ *
320
+ * @param client - Fetch client instance
321
+ * @param asset_code - asset_code
322
+ * @param body - body
323
+ */
324
+ async function dam_asset_paths_create(client, asset_code, body) {
325
+ return client.post(`/api/content/dam/assets/${asset_code}/paths`, body);
326
+ }
327
+ //#endregion
328
+ //#region ../../shareables/api-client/src/portal-tenant-media-adapter.ts
329
+ /**
330
+ * Maps a BFF media object to the port's Media shape, providing defaults
331
+ * for optional fields returned by the generated client.
332
+ */
333
+ function mapMedia(raw) {
334
+ return {
335
+ id: raw.id ?? 0,
336
+ title: raw.title ?? "",
337
+ description: raw.description ?? null,
338
+ media_type: raw.media_type ?? "",
339
+ url: raw.url ?? null,
340
+ thumbnail_url: raw.thumbnail_url ?? null,
341
+ owner_type: raw.owner_type ?? "",
342
+ created_at: raw.created_at ?? "",
343
+ updated_at: raw.updated_at ?? ""
344
+ };
345
+ }
346
+ /**
347
+ * Maps the BFF meta envelope to the port's ApiMeta shape.
348
+ */
349
+ function mapMeta$3(raw) {
350
+ return {
351
+ request_id: raw?.request_id ?? null,
352
+ timestamp: raw?.timestamp ?? "",
353
+ pagination: raw?.pagination ? {
354
+ cursor: raw.pagination.cursor ?? null,
355
+ limit: raw.pagination.limit,
356
+ next_cursor: raw.pagination.next_cursor ?? null,
357
+ prev_cursor: raw.pagination.prev_cursor ?? null
358
+ } : void 0
359
+ };
360
+ }
361
+ /**
362
+ * Creates a ContentMediaApi adapter backed by the portal-tenant content BFF.
363
+ *
364
+ * Maps the generated portal-tenant-content namespace functions to the abstract
365
+ * ContentMediaApi port, closing over the FetchClient so consumers don't need
366
+ * to pass it per-call.
367
+ */
368
+ function createPortalTenantMediaAdapter(client) {
369
+ return {
370
+ listMedia: async (params) => {
371
+ const response = await media_list(client, {
372
+ "page[cursor]": params?.cursor,
373
+ "page[limit]": params?.limit,
374
+ media_type: params?.media_type,
375
+ "filter[title]": params?.["filter[title]"],
376
+ sort: params?.sort
377
+ });
378
+ return {
379
+ media: (response.media ?? []).map(mapMedia),
380
+ meta: mapMeta$3(response.meta)
381
+ };
382
+ },
383
+ createMedia: async (body) => {
384
+ const response = await media_create(client, { media: body });
385
+ return {
386
+ media: mapMedia(response.media ?? {}),
387
+ meta: mapMeta$3(response.meta)
388
+ };
389
+ },
390
+ getMedia: async (id) => {
391
+ const response = await media_show(client, id);
392
+ return {
393
+ media: mapMedia(response.media ?? {}),
394
+ meta: mapMeta$3(response.meta)
395
+ };
396
+ },
397
+ updateMedia: async (id, body) => {
398
+ const response = await media_update(client, id, { media: body });
399
+ return {
400
+ media: mapMedia(response.media ?? {}),
401
+ meta: mapMeta$3(response.meta)
402
+ };
403
+ },
404
+ deleteMedia: async (id) => {
405
+ const response = await media_destroy(client, id);
406
+ return {
407
+ media: { id: response.media?.id ?? 0 },
408
+ meta: mapMeta$3(response.meta)
409
+ };
410
+ }
411
+ };
412
+ }
413
+ function mediaKindFromType$1(mediaType) {
414
+ if (mediaType === "video") return "video";
415
+ if (mediaType === "image") return "image";
416
+ if (mediaType === "document" || mediaType === "pdf") return "pdf";
417
+ return null;
418
+ }
419
+ function toBffMediumResponse(bff) {
420
+ const kind = mediaKindFromType$1(bff.media_type);
421
+ const isVideo = bff.media_type === "video";
422
+ const isPdf = bff.media_type === "pdf" || bff.media_type === "document";
423
+ return {
424
+ id: bff.id,
425
+ user_id: null,
426
+ media_type: bff.media_type,
427
+ media_format: bff.media_type,
428
+ image_url: !isVideo && !isPdf ? bff.url ?? bff.thumbnail_url ?? null : bff.thumbnail_url ?? null,
429
+ video_url: isVideo ? bff.url ?? null : null,
430
+ pdf_url: isPdf ? bff.url ?? null : null,
431
+ title: bff.title,
432
+ description: {
433
+ id: null,
434
+ name: null,
435
+ body: bff.description ?? null,
436
+ record_type: null,
437
+ record_id: null,
438
+ created_at: bff.created_at ?? null,
439
+ updated_at: bff.updated_at ?? null,
440
+ locale: null
441
+ },
442
+ stripped: bff.description ?? null,
443
+ kind,
444
+ active: true,
445
+ visibility: null,
446
+ share_link: null,
447
+ views: 0,
448
+ leads: 0,
449
+ watch: null,
450
+ video_status: null,
451
+ duration: null,
452
+ cta_url: null,
453
+ cta_button_text: null,
454
+ cta_enabled: false,
455
+ cta_action_type: null,
456
+ video_shopping_enabled: false,
457
+ prompts_enabled: false,
458
+ ranks: [],
459
+ preview_link: null,
460
+ attached_shareables: [],
461
+ created_at: bff.created_at
462
+ };
463
+ }
464
+ /**
465
+ * Creates a ShareablesApi["media"]-compatible adapter backed by the
466
+ * portal-tenant content BFF. Includes cursor-to-page-number caching
467
+ * for bridging the legacy UI's page-number pagination.
468
+ */
469
+ function createPortalTenantMediaShareablesAdapter(client) {
470
+ const portAdapter = createPortalTenantMediaAdapter(client);
471
+ const cursorByPage = /* @__PURE__ */ new Map();
472
+ let lastFilterKey = "";
473
+ return {
474
+ getMedia: async (options) => {
475
+ const pageNumber = options?.page ?? 1;
476
+ const filterKey = `${options?.search_query ?? ""}|${options?.sorted_by ?? ""}|${options?.media_type ?? options?.with_type ?? ""}`;
477
+ if (filterKey !== lastFilterKey) {
478
+ cursorByPage.clear();
479
+ lastFilterKey = filterKey;
480
+ }
481
+ const cursor = pageNumber > 1 ? cursorByPage.get(pageNumber) : void 0;
482
+ const rawSort = options?.sorted_by;
483
+ let bffSort;
484
+ if (rawSort === "title_asc") bffSort = "title_asc";
485
+ else if (rawSort === "title_desc") bffSort = "title_desc";
486
+ const response = await portAdapter.listMedia({
487
+ cursor,
488
+ limit: options?.per_page,
489
+ media_type: options?.media_type ?? options?.with_type,
490
+ "filter[title]": options?.search_query,
491
+ sort: bffSort
492
+ });
493
+ const nextCursor = response.meta.pagination?.next_cursor;
494
+ if (nextCursor) cursorByPage.set(pageNumber + 1, nextCursor);
495
+ const transformedItems = response.media.map(toBffMediumResponse);
496
+ return {
497
+ data: transformedItems,
498
+ status: "success",
499
+ media: transformedItems,
500
+ meta: {
501
+ total_count: transformedItems.length,
502
+ current: pageNumber,
503
+ per_page: options?.per_page ?? 24,
504
+ pages: nextCursor ? pageNumber + 1 : pageNumber,
505
+ next: nextCursor ? pageNumber + 1 : null,
506
+ previous: pageNumber > 1 ? pageNumber - 1 : null
507
+ }
508
+ };
509
+ },
510
+ getMediaById: async (id) => {
511
+ const medium = toBffMediumResponse((await portAdapter.getMedia(id)).media);
512
+ return {
513
+ data: medium,
514
+ status: "success",
515
+ media: medium
516
+ };
517
+ },
518
+ createMedia: async (mediaData) => {
519
+ return toBffMediumResponse((await portAdapter.createMedia({
520
+ title: mediaData.title ?? "",
521
+ description: mediaData.description,
522
+ media_type: mediaData.media_type ?? "image",
523
+ url: mediaData.image_url ?? mediaData.video_url ?? mediaData.pdf_url ?? void 0
524
+ })).media);
525
+ },
526
+ updateMedia: async (id, mediaData) => {
527
+ return toBffMediumResponse((await portAdapter.updateMedia(id, {
528
+ title: mediaData.title,
529
+ description: mediaData.description
530
+ })).media);
531
+ },
532
+ deleteMedia: async (id) => {
533
+ await portAdapter.deleteMedia(id);
534
+ return { success: true };
535
+ }
536
+ };
537
+ }
538
+ //#endregion
539
+ //#region ../../shareables/api-client/src/portal-tenant-playlists-adapter.ts
540
+ /**
541
+ * Maps a BFF playlist object to the port's Playlist shape.
542
+ */
543
+ function mapPlaylist(raw) {
544
+ return {
545
+ id: raw.id ?? 0,
546
+ title: raw.title ?? "",
547
+ description: raw.description ?? null,
548
+ items_count: raw.items_count ?? 0,
549
+ user_id: raw.user_id,
550
+ is_favorited: raw.is_favorited,
551
+ image_url: raw.image_url ?? null,
552
+ created_at: raw.created_at ?? "",
553
+ updated_at: raw.updated_at ?? ""
554
+ };
555
+ }
556
+ /**
557
+ * Maps a BFF playlist item to the port's PlaylistItem shape.
558
+ */
559
+ function mapPlaylistItem(raw) {
560
+ return {
561
+ id: raw.id ?? 0,
562
+ media_id: raw.media_id ?? 0,
563
+ position: raw.position ?? null,
564
+ title: raw.title,
565
+ image_url: raw.image_url ?? null,
566
+ media_type: raw.media_type,
567
+ video_url: raw.video_url ?? null,
568
+ duration: raw.duration ?? null,
569
+ created_at: raw.created_at ?? ""
570
+ };
571
+ }
572
+ /**
573
+ * Maps the BFF meta envelope to the port's ApiMeta shape.
574
+ */
575
+ function mapMeta$2(raw) {
576
+ return {
577
+ request_id: raw?.request_id ?? null,
578
+ timestamp: raw?.timestamp ?? "",
579
+ pagination: raw?.pagination ? {
580
+ cursor: raw.pagination.cursor ?? null,
581
+ limit: raw.pagination.limit,
582
+ next_cursor: raw.pagination.next_cursor ?? null,
583
+ prev_cursor: raw.pagination.prev_cursor ?? null
584
+ } : void 0
585
+ };
586
+ }
587
+ /**
588
+ * Creates a ContentPlaylistsApi adapter backed by the portal-tenant content BFF.
589
+ *
590
+ * Maps the generated portal-tenant-content namespace functions to the abstract
591
+ * ContentPlaylistsApi port, closing over the FetchClient so consumers don't
592
+ * need to pass it per-call.
593
+ */
594
+ function createPortalTenantPlaylistsAdapter(client) {
595
+ return {
596
+ listPlaylists: async (params) => {
597
+ const response = await playlists_list(client, {
598
+ "page[cursor]": params?.cursor,
599
+ "page[limit]": params?.limit,
600
+ "filter[title]": params?.["filter[title]"],
601
+ sort: params?.sort
602
+ });
603
+ return {
604
+ playlists: (response.playlists ?? []).map(mapPlaylist),
605
+ meta: mapMeta$2(response.meta)
606
+ };
607
+ },
608
+ createPlaylist: async (body) => {
609
+ const response = await playlists_create(client, { playlist: body });
610
+ return {
611
+ playlist: mapPlaylist(response.playlist ?? {}),
612
+ meta: mapMeta$2(response.meta)
613
+ };
614
+ },
615
+ getPlaylist: async (id) => {
616
+ const response = await playlists_show(client, id);
617
+ return {
618
+ playlist: mapPlaylist(response.playlist ?? {}),
619
+ meta: mapMeta$2(response.meta)
620
+ };
621
+ },
622
+ updatePlaylist: async (id, body) => {
623
+ const response = await playlists_update(client, id, { playlist: body });
624
+ return {
625
+ playlist: mapPlaylist(response.playlist ?? {}),
626
+ meta: mapMeta$2(response.meta)
627
+ };
628
+ },
629
+ deletePlaylist: async (id) => {
630
+ const response = await playlists_destroy(client, id);
631
+ return {
632
+ playlist: { id: response.playlist?.id ?? 0 },
633
+ meta: mapMeta$2(response.meta)
634
+ };
635
+ },
636
+ listPlaylistItems: async (playlistId, params) => {
637
+ const response = await playlists_items_list(client, playlistId, {
638
+ "page[cursor]": params?.cursor,
639
+ "page[limit]": params?.limit
640
+ });
641
+ return {
642
+ playlist_items: (response.playlist_items ?? []).map(mapPlaylistItem),
643
+ meta: mapMeta$2(response.meta)
644
+ };
645
+ },
646
+ addPlaylistItem: async (playlistId, body) => {
647
+ const response = await playlists_items_add(client, playlistId, { item: body });
648
+ return {
649
+ playlist_item: mapPlaylistItem(response.playlist_item ?? {}),
650
+ meta: mapMeta$2(response.meta)
651
+ };
652
+ },
653
+ removePlaylistItem: async (playlistId, itemId) => {
654
+ const response = await playlists_items_remove(client, playlistId, itemId);
655
+ return {
656
+ playlist_item: { id: response.playlist_item?.id ?? 0 },
657
+ meta: mapMeta$2(response.meta)
658
+ };
659
+ }
660
+ };
661
+ }
662
+ function mediaKindFromType(mediaType) {
663
+ if (mediaType === "video") return "video";
664
+ if (mediaType === "image") return "image";
665
+ if (mediaType === "document" || mediaType === "pdf") return "pdf";
666
+ return null;
667
+ }
668
+ function toBffPlaylist(bff, items) {
669
+ return {
670
+ id: bff.id,
671
+ title: bff.title,
672
+ description: bff.description ?? null,
673
+ image_url: bff.image_url ?? null,
674
+ slug: null,
675
+ active: true,
676
+ user_id: bff.user_id ?? null,
677
+ is_favorited: bff.is_favorited ?? false,
678
+ items: items ?? [],
679
+ items_count: bff.items_count
680
+ };
681
+ }
682
+ /**
683
+ * Creates a ShareablesApi["playlists"]-compatible adapter backed by the
684
+ * portal-tenant content BFF. Fetches playlist + items in parallel for
685
+ * detail views and maps enriched flat fields onto playlist items.
686
+ */
687
+ function createPortalTenantPlaylistsShareablesAdapter(client) {
688
+ const portAdapter = createPortalTenantPlaylistsAdapter(client);
689
+ return {
690
+ getPlaylists: async (options) => {
691
+ const rawSort = options?.sort;
692
+ let bffSort;
693
+ if (rawSort === "title_asc" || rawSort === "title") bffSort = "title_asc";
694
+ else if (rawSort === "title_desc" || rawSort === "-title") bffSort = "title_desc";
695
+ else if (rawSort === "created_at_asc" || rawSort === "created_at") bffSort = "created_at_asc";
696
+ else if (rawSort === "created_at_desc" || rawSort === "-created_at") bffSort = "created_at_desc";
697
+ const response = await portAdapter.listPlaylists({
698
+ cursor: options?.["page[cursor]"],
699
+ limit: options?.["page[limit]"],
700
+ "filter[title]": options?.["filter[title]"],
701
+ sort: bffSort
702
+ });
703
+ return {
704
+ playlists: response.playlists.map((p) => toBffPlaylist(p)),
705
+ meta: {
706
+ request_id: response.meta.request_id ?? "",
707
+ timestamp: response.meta.timestamp ?? "",
708
+ pagination: {
709
+ cursor: response.meta.pagination?.cursor ?? null,
710
+ limit: response.meta.pagination?.limit ?? 12,
711
+ prev_cursor: response.meta.pagination?.prev_cursor ?? null,
712
+ next_cursor: response.meta.pagination?.next_cursor ?? null,
713
+ total_count: 0,
714
+ total_pages: 0
715
+ }
716
+ }
717
+ };
718
+ },
719
+ getPlaylistById: async (id) => {
720
+ const response = await portAdapter.getPlaylist(id);
721
+ const allItems = [];
722
+ let cursor;
723
+ const MAX_PAGES = 50;
724
+ for (let i = 0; i < MAX_PAGES; i++) {
725
+ const page = await portAdapter.listPlaylistItems(id, {
726
+ cursor,
727
+ limit: 100
728
+ });
729
+ allItems.push(...page.playlist_items);
730
+ cursor = page.meta.pagination?.next_cursor ?? void 0;
731
+ if (!cursor) break;
732
+ }
733
+ const items = allItems.map((item) => ({
734
+ id: item.id,
735
+ order: item.position ?? void 0,
736
+ relateable_type: "Medium",
737
+ relateable: { id: item.media_id },
738
+ title: item.title ?? "Untitled",
739
+ image_url: item.image_url ?? null,
740
+ kind: mediaKindFromType(item.media_type ?? ""),
741
+ video_url: item.video_url ?? null,
742
+ duration: item.duration ?? null,
743
+ media_format: item.media_type ?? null
744
+ }));
745
+ return {
746
+ playlist: toBffPlaylist(response.playlist, items),
747
+ meta: {
748
+ request_id: response.meta.request_id ?? "",
749
+ timestamp: response.meta.timestamp ?? ""
750
+ }
751
+ };
752
+ },
753
+ createPlaylist: async (data) => {
754
+ const response = await portAdapter.createPlaylist({
755
+ title: data.playlist.title,
756
+ description: data.playlist.description
757
+ });
758
+ return {
759
+ playlist: toBffPlaylist(response.playlist),
760
+ meta: {
761
+ request_id: response.meta.request_id ?? "",
762
+ timestamp: response.meta.timestamp ?? ""
763
+ }
764
+ };
765
+ },
766
+ updatePlaylist: async (id, data) => {
767
+ const response = await portAdapter.updatePlaylist(id, {
768
+ title: data.playlist.title,
769
+ description: data.playlist.description
770
+ });
771
+ return {
772
+ playlist: toBffPlaylist(response.playlist),
773
+ meta: {
774
+ request_id: response.meta.request_id ?? "",
775
+ timestamp: response.meta.timestamp ?? ""
776
+ }
777
+ };
778
+ },
779
+ addItemToPlaylist: async (id, data) => {
780
+ await Promise.all(data.items.map((item) => portAdapter.addPlaylistItem(id, {
781
+ media_id: item.relateable_id,
782
+ position: typeof item.order === "number" ? item.order : Number(item.order)
783
+ })));
784
+ return toBffPlaylist((await portAdapter.getPlaylist(id)).playlist);
785
+ },
786
+ removeItemsFromPlaylist: async (playlistId, data) => {
787
+ await Promise.all(data.item_ids.map((itemId) => portAdapter.removePlaylistItem(playlistId, itemId)));
788
+ return toBffPlaylist((await portAdapter.getPlaylist(playlistId)).playlist);
789
+ }
790
+ };
791
+ }
792
+ //#endregion
793
+ //#region ../../shareables/api-client/src/portal-tenant-dam-assets-adapter.ts
794
+ /**
795
+ * Maps a BFF DAM asset to the port's DamAsset shape.
796
+ */
797
+ function mapDamAsset(raw) {
798
+ return {
799
+ id: raw.id ?? 0,
800
+ code: raw.code ?? "",
801
+ name: raw.name ?? "",
802
+ content_type: raw.content_type ?? null,
803
+ byte_size: raw.byte_size ?? null,
804
+ url: raw.url ?? null,
805
+ created_at: raw.created_at ?? "",
806
+ updated_at: raw.updated_at ?? ""
807
+ };
808
+ }
809
+ /**
810
+ * Maps a BFF DAM asset path to the port's DamAssetPath shape.
811
+ */
812
+ function mapDamAssetPath(raw) {
813
+ return {
814
+ id: raw.id ?? 0,
815
+ asset_code: raw.asset_code ?? "",
816
+ path: raw.path ?? "",
817
+ created_at: raw.created_at ?? ""
818
+ };
819
+ }
820
+ /**
821
+ * Maps the BFF meta envelope to the port's ApiMeta shape.
822
+ */
823
+ function mapMeta$1(raw) {
824
+ return {
825
+ request_id: raw?.request_id ?? null,
826
+ timestamp: raw?.timestamp ?? "",
827
+ pagination: raw?.pagination ? {
828
+ cursor: raw.pagination.cursor ?? null,
829
+ limit: raw.pagination.limit,
830
+ next_cursor: raw.pagination.next_cursor ?? null,
831
+ prev_cursor: raw.pagination.prev_cursor ?? null
832
+ } : void 0
833
+ };
834
+ }
835
+ /**
836
+ * Creates a ContentDamAssetsApi adapter backed by the portal-tenant content BFF.
837
+ *
838
+ * Maps the generated portal-tenant-content namespace functions to the abstract
839
+ * ContentDamAssetsApi port, closing over the FetchClient so consumers don't
840
+ * need to pass it per-call.
841
+ */
842
+ function createPortalTenantDamAssetsAdapter(client) {
843
+ return {
844
+ listAssets: async (params) => {
845
+ const response = await dam_assets_list(client, {
846
+ "page[cursor]": params?.cursor,
847
+ "page[limit]": params?.limit
848
+ });
849
+ return {
850
+ assets: (response.assets ?? []).map(mapDamAsset),
851
+ meta: mapMeta$1(response.meta)
852
+ };
853
+ },
854
+ createAsset: async (body) => {
855
+ const response = await dam_assets_create(client, { asset: body });
856
+ return {
857
+ asset: mapDamAsset(response.asset ?? {}),
858
+ meta: mapMeta$1(response.meta)
859
+ };
860
+ },
861
+ listAssetPaths: async (assetCode, params) => {
862
+ const response = await dam_asset_paths_list(client, assetCode, {
863
+ "page[cursor]": params?.cursor,
864
+ "page[limit]": params?.limit
865
+ });
866
+ return {
867
+ asset_paths: (response.asset_paths ?? []).map(mapDamAssetPath),
868
+ meta: mapMeta$1(response.meta)
869
+ };
870
+ },
871
+ createAssetPath: async (assetCode, body) => {
872
+ const response = await dam_asset_paths_create(client, assetCode, { asset_path: body });
873
+ return {
874
+ asset_path: mapDamAssetPath(response.asset_path ?? {}),
875
+ meta: mapMeta$1(response.meta)
876
+ };
877
+ }
878
+ };
879
+ }
880
+ /**
881
+ * Creates a ShareablesApi["fileResources"]-compatible adapter backed by the
882
+ * portal-tenant content BFF. Maps DamAsset to FileResource shape and
883
+ * includes cursor-to-page-number caching for legacy UI pagination.
884
+ */
885
+ function createPortalTenantFilesShareablesAdapter(client) {
886
+ const portAdapter = createPortalTenantDamAssetsAdapter(client);
887
+ const cursorByPage = /* @__PURE__ */ new Map();
888
+ return { getFileResources: async (params) => {
889
+ const pageNumber = params?.pageParam ? Number(params.pageParam) : 1;
890
+ const pageSize = params?.pageSize ? Number(params.pageSize) : 25;
891
+ const cursor = pageNumber > 1 ? cursorByPage.get(pageNumber) : void 0;
892
+ const response = await portAdapter.listAssets({
893
+ cursor,
894
+ limit: pageSize
895
+ });
896
+ const nextCursor = response.meta.pagination?.next_cursor;
897
+ if (nextCursor) cursorByPage.set(pageNumber + 1, nextCursor);
898
+ const fileResources = response.assets.map((asset) => ({
899
+ id: asset.id,
900
+ alt_text: asset.name,
901
+ url: asset.url ?? "",
902
+ filename: asset.name,
903
+ content_type: asset.content_type ?? "application/octet-stream",
904
+ content_size: asset.byte_size ?? 0,
905
+ handle: asset.code,
906
+ dam_asset_code: asset.code,
907
+ preview_image_url: asset.url ?? "",
908
+ created_at: asset.created_at,
909
+ updated_at: asset.updated_at,
910
+ relateable_type: null,
911
+ relateable_id: null,
912
+ content: null
913
+ }));
914
+ const hasNextPage = !!nextCursor;
915
+ return {
916
+ file_resources: fileResources,
917
+ meta: {
918
+ total_count: fileResources.length,
919
+ per_page: pageSize,
920
+ current_page: pageNumber,
921
+ total_pages: hasNextPage ? pageNumber + 1 : pageNumber
922
+ }
923
+ };
924
+ } };
925
+ }
926
+ //#endregion
927
+ //#region ../../shareables/api-client/src/portal-tenant-shares-adapter.ts
928
+ /**
929
+ * Narrows an unknown string to a valid ShareableType at runtime.
930
+ */
931
+ function isShareableType(value) {
932
+ return value === "media" || value === "product" || value === "library" || value === "page";
933
+ }
934
+ /**
935
+ * Maps a BFF share to the port's Share shape.
936
+ */
937
+ function mapShare(raw) {
938
+ return {
939
+ id: raw.id ?? 0,
940
+ url: raw.url ?? "",
941
+ shareable_type: isShareableType(raw.shareable_type) ? raw.shareable_type : "media",
942
+ shareable_id: raw.shareable_id ?? 0,
943
+ created_at: raw.created_at ?? ""
944
+ };
945
+ }
946
+ /**
947
+ * Maps the BFF meta envelope to the port's ApiMeta shape.
948
+ */
949
+ function mapMeta(raw) {
950
+ return {
951
+ request_id: raw?.request_id ?? null,
952
+ timestamp: raw?.timestamp ?? "",
953
+ pagination: raw?.pagination ? {
954
+ cursor: raw.pagination.cursor ?? null,
955
+ limit: raw.pagination.limit,
956
+ next_cursor: raw.pagination.next_cursor ?? null,
957
+ prev_cursor: raw.pagination.prev_cursor ?? null
958
+ } : void 0
959
+ };
960
+ }
961
+ /**
962
+ * Creates a ContentSharesApi adapter backed by the portal-tenant content BFF.
963
+ *
964
+ * Maps the generated portal-tenant-content namespace functions to the abstract
965
+ * ContentSharesApi port, closing over the FetchClient so consumers don't need
966
+ * to pass it per-call.
967
+ */
968
+ function createPortalTenantSharesAdapter(client) {
969
+ return {
970
+ listShares: async (params) => {
971
+ const response = await shares_list(client, {
972
+ "page[cursor]": params?.cursor,
973
+ "page[limit]": params?.limit
974
+ });
975
+ return {
976
+ shares: (response.shares ?? []).map(mapShare),
977
+ meta: mapMeta(response.meta)
978
+ };
979
+ },
980
+ createShare: async (body) => {
981
+ const response = await shares_create(client, { share: body });
982
+ return {
983
+ share: mapShare(response.share ?? {}),
984
+ meta: mapMeta(response.meta)
985
+ };
986
+ }
987
+ };
988
+ }
989
+ /**
990
+ * Maps legacy Rails model names (used by the UI) to BFF shareable_type values.
991
+ */
992
+ const SHAREABLE_TYPE_MAP = {
993
+ Medium: "media",
994
+ media: "media",
995
+ Product: "product",
996
+ product: "product",
997
+ Library: "library",
998
+ library: "library",
999
+ Page: "page",
1000
+ page: "page"
1001
+ };
1002
+ /**
1003
+ * Creates a ShareablesApi["share"]-compatible adapter backed by the
1004
+ * portal-tenant content BFF. Maps legacy model names to BFF shareable types.
1005
+ */
1006
+ function createPortalTenantSharesShareablesAdapter(client) {
1007
+ const portAdapter = createPortalTenantSharesAdapter(client);
1008
+ return { createShareLink: async (input) => {
1009
+ if (!input.relateableId) throw new Error("Cannot create share link without a relateableId");
1010
+ const shareableType = SHAREABLE_TYPE_MAP[input.relateableType];
1011
+ if (!shareableType) throw new Error(`Unknown shareable type: "${input.relateableType}"`);
1012
+ return (await portAdapter.createShare({
1013
+ shareable_type: shareableType,
1014
+ shareable_id: input.relateableId
1015
+ })).share.url;
1016
+ } };
1017
+ }
1018
+ //#endregion
1019
+ //#region ../../file-picker/api-client/src/client.ts
1020
+ function createFilePickerClient(config) {
1021
+ return {
1022
+ fetchClient: config.fetchClient,
1023
+ uploadStrategy: config.uploadStrategy,
1024
+ unsplashAccessKey: config.unsplashAccessKey,
1025
+ proxyEndpoint: config.proxyEndpoint ?? "/api/proxy-url"
1026
+ };
1027
+ }
1028
+ //#endregion
1029
+ //#region ../../file-picker/api-client/src/api/dam-assets.ts
1030
+ /**
1031
+ * Create a DAM asset. Text files use FormData upload; non-text files
1032
+ * delegate to the provided uploadStrategy (e.g. ImageKit).
1033
+ * If no uploadStrategy is provided, all files use FormData upload.
1034
+ */
1035
+ async function createDamAsset(fetchClient, params, uploadStrategy) {
1036
+ const mimeType = getFileMimeType(params.file);
1037
+ if (mimeType.startsWith("text/") || mimeType === "application/json" || mimeType === "application/xml" || params.file.name.endsWith(".txt") || params.file.name.endsWith(".json") || params.file.name.endsWith(".xml") || params.file.name.endsWith(".csv")) return createDamAssetViaFormData(fetchClient, params);
1038
+ if (uploadStrategy) return uploadStrategy.uploadFile(params);
1039
+ return createDamAssetViaFormData(fetchClient, params);
1040
+ }
1041
+ async function createDamAssetViaFormData(fetchClient, params) {
1042
+ const formData = new FormData();
1043
+ formData.append("asset[file]", params.file);
1044
+ formData.append("asset[name]", params.name);
1045
+ if (params.description) formData.append("asset[description]", params.description);
1046
+ if (params.tags && params.tags.length > 0) formData.append("asset[tags]", params.tags.join(","));
1047
+ const response = await fetchClient.requestWithFormData("/dam/assets", formData, { method: "POST" });
1048
+ return damAssetCreateResponseSchema.parse(response);
1049
+ }
1050
+ async function createDamAssetPathForAssets(fetchClient, { asset_paths, code }) {
1051
+ const response = await fetchClient.post(`/dam/assets/${code}/asset_paths`, { asset_paths });
1052
+ return damAssetPathCreateResponseSchema.parse(response);
1053
+ }
1054
+ //#endregion
1055
+ //#region ../../file-picker/api-client/src/api/dam-query.ts
1056
+ async function queryDamAssets(fetchClient, params) {
1057
+ const response = await fetchClient.post("/dam/query", params);
1058
+ return damQueryResponseSchema.parse(response);
1059
+ }
1060
+ async function deleteDamAsset(fetchClient, code) {
1061
+ return fetchClient.delete(`/dam/assets/${code}`);
1062
+ }
1063
+ async function discardDamAsset(fetchClient, code) {
1064
+ return fetchClient.patch(`/dam/assets/${code}/discard`);
1065
+ }
1066
+ //#endregion
1067
+ //#region ../../file-picker/api-client/src/api/unsplash.ts
1068
+ const unsplashImageSchema = z.object({
1069
+ id: z.string(),
1070
+ urls: z.object({
1071
+ raw: z.string(),
1072
+ full: z.string(),
1073
+ regular: z.string(),
1074
+ small: z.string(),
1075
+ thumb: z.string()
1076
+ }),
1077
+ alt_description: z.string().nullable(),
1078
+ description: z.string().nullable(),
1079
+ user: z.object({
1080
+ name: z.string(),
1081
+ username: z.string()
1082
+ }),
1083
+ width: z.number(),
1084
+ height: z.number()
1085
+ });
1086
+ const unsplashSearchResponseSchema = z.object({
1087
+ results: z.array(unsplashImageSchema),
1088
+ total: z.number(),
1089
+ total_pages: z.number()
1090
+ });
1091
+ /**
1092
+ * Search Unsplash for photos matching a query.
1093
+ */
1094
+ async function searchUnsplash(query, accessKey, page = 1, perPage = 20) {
1095
+ const response = await fetch(`https://api.unsplash.com/search/photos?query=${encodeURIComponent(query)}&page=${page}&per_page=${perPage}&client_id=${accessKey}`);
1096
+ if (!response.ok) throw new Error("Failed to search Unsplash");
1097
+ return unsplashSearchResponseSchema.parse(await response.json());
1098
+ }
1099
+ //#endregion
1100
+ //#region ../../file-picker/api-client/src/api/url-proxy.ts
1101
+ const urlProxyResponseSchema = z.object({
1102
+ data: z.string(),
1103
+ contentType: z.string(),
1104
+ size: z.number()
1105
+ });
1106
+ /**
1107
+ * Proxy a URL fetch through the backend to bypass CORS restrictions.
1108
+ * The backend fetches the file and returns it as base64-encoded data.
1109
+ *
1110
+ * @param url - The URL to fetch
1111
+ * @param proxyEndpoint - The proxy endpoint (defaults to "/api/proxy-url")
1112
+ */
1113
+ async function proxyUrlFetch(url, proxyEndpoint = "/api/proxy-url") {
1114
+ const response = await fetch(proxyEndpoint, {
1115
+ method: "POST",
1116
+ headers: { "Content-Type": "application/json" },
1117
+ body: JSON.stringify({ url })
1118
+ });
1119
+ if (!response.ok) {
1120
+ const errorData = await response.json().catch(() => ({ error: "Failed to proxy URL fetch" }));
1121
+ throw new Error(errorData.error || `HTTP ${response.status}`);
1122
+ }
1123
+ const data = await response.json();
1124
+ return urlProxyResponseSchema.parse(data);
1125
+ }
1126
+ //#endregion
1127
+ //#region ../../file-picker/api-client/src/create-file-picker-api.ts
1128
+ /**
1129
+ * Creates a FilePickerApi-compatible adapter backed by the real API client
1130
+ * functions. The returned object satisfies the FilePickerApi interface
1131
+ * from @fluid-app/file-picker-core via structural typing.
1132
+ */
1133
+ function createFilePickerApi(client) {
1134
+ return {
1135
+ createDamAsset: (params) => createDamAsset(client.fetchClient, params, client.uploadStrategy),
1136
+ queryDamAssets: (params) => queryDamAssets(client.fetchClient, params),
1137
+ searchUnsplash: (query, page, perPage) => {
1138
+ if (!client.unsplashAccessKey) throw new Error("Unsplash access key not configured");
1139
+ return searchUnsplash(query, client.unsplashAccessKey, page, perPage);
1140
+ },
1141
+ deleteDamAsset: (code) => deleteDamAsset(client.fetchClient, code),
1142
+ discardDamAsset: (code) => discardDamAsset(client.fetchClient, code),
1143
+ createDamAssetPathForAssets: (params) => createDamAssetPathForAssets(client.fetchClient, params),
1144
+ proxyUrlFetch: (url) => proxyUrlFetch(url, client.proxyEndpoint)
1145
+ };
1146
+ }
1147
+ //#endregion
1148
+ //#region src/screens/ShareablesScreen.tsx
1149
+ /**
1150
+ * Parse the current shareables sub-route from the full slug.
1151
+ *
1152
+ * System nav slugs are "share/products", "share/media", "share/playlists".
1153
+ * Detail pages append an ID: "share/products/123", "share/media/456".
1154
+ *
1155
+ * "share/products" → screen="products", detailId=null
1156
+ * "share/products/123" → screen="products", detailId="123"
1157
+ * "share/media/456" → screen="media", detailId="456"
1158
+ * "share/playlists" → screen="playlists", detailId=null
1159
+ * "share/playlists/789" → screen="playlists", detailId="789"
1160
+ * "share/files" → screen="files", detailId=null
1161
+ * "share" → screen=null (default to products)
1162
+ */
1163
+ function parseShareablesRoute(currentSlug) {
1164
+ const slugWithoutPrefix = currentSlug.replace(/^share\/?/, "");
1165
+ if (!slugWithoutPrefix) return {
1166
+ screen: null,
1167
+ detailId: null,
1168
+ action: null
1169
+ };
1170
+ const parts = slugWithoutPrefix.split("/");
1171
+ return {
1172
+ screen: parts[0] || null,
1173
+ detailId: parts[1] || null,
1174
+ action: parts[2] || null
1175
+ };
1176
+ }
1177
+ function ShareablesScreen({ background, textColor, accentColor, padding, borderRadius, ...divProps }) {
1178
+ const domainClient = useSdkClient();
1179
+ const portalProductsApi = usePortalProductsClient();
1180
+ const portalTenantClient = usePortalTenantClient();
1181
+ const { data: userData } = useCurrentUser();
1182
+ const { currentSlug, navigate } = useAppNavigation();
1183
+ const { isCustomer } = useUserType();
1184
+ const fetchProducts = useCallback(async (search, cursor, limit) => {
1185
+ if (search) return portalProductsApi.searchProducts(search, {
1186
+ cursor,
1187
+ limit
1188
+ });
1189
+ return portalProductsApi.listProducts({
1190
+ cursor,
1191
+ limit
1192
+ });
1193
+ }, [portalProductsApi]);
1194
+ const fetchProduct = useCallback(async (id) => portalProductsApi.getProduct(id), [portalProductsApi]);
1195
+ const { screen, detailId, action } = parseShareablesRoute(currentSlug);
1196
+ const handleNavigate = useCallback((subScreen, id) => {
1197
+ navigate(id ? `share/${subScreen}/${id}` : `share/${subScreen}`);
1198
+ }, [navigate]);
1199
+ const handleBack = useCallback(() => {
1200
+ if (detailId && screen) navigate(`share/${screen}`);
1201
+ else navigate("share/products");
1202
+ }, [
1203
+ navigate,
1204
+ detailId,
1205
+ screen
1206
+ ]);
1207
+ const coreConfig = useMemo(() => ({
1208
+ client: domainClient,
1209
+ user: userData ? { id: userData.id } : null,
1210
+ repContext: true
1211
+ }), [domainClient, userData]);
1212
+ const playlistsAdapter = useMemo(() => createPortalTenantPlaylistsAdapter(portalTenantClient), [portalTenantClient]);
1213
+ const shareablesApi = useMemo(() => ({
1214
+ media: createPortalTenantMediaShareablesAdapter(portalTenantClient),
1215
+ playlists: createPortalTenantPlaylistsShareablesAdapter(portalTenantClient),
1216
+ fileResources: createPortalTenantFilesShareablesAdapter(portalTenantClient),
1217
+ share: createPortalTenantSharesShareablesAdapter(portalTenantClient),
1218
+ productMedia: { getProductMedia: async (productId) => {
1219
+ return { media: ((await portalProductsApi.getProductMedia(productId)).media ?? []).map((item) => {
1220
+ const isVideo = item.media_type === "video";
1221
+ const isPdf = item.media_type === "pdf" || item.media_type === "document";
1222
+ return {
1223
+ id: item.id ?? 0,
1224
+ slug: null,
1225
+ title: item.title ?? "",
1226
+ kind: isVideo ? "video" : isPdf ? "pdf" : "image",
1227
+ media_type: item.media_type ?? "image",
1228
+ media_format: item.media_type ?? "image",
1229
+ image_url: !isVideo && !isPdf ? item.url ?? null : null,
1230
+ video_url: isVideo ? item.url ?? null : null,
1231
+ pdf_url: isPdf ? item.url ?? null : null,
1232
+ powerpoint_url: null,
1233
+ duration: 0,
1234
+ description: null,
1235
+ subtitles: {},
1236
+ comments_count: 0
1237
+ };
1238
+ }) };
1239
+ } }
1240
+ }), [portalTenantClient, portalProductsApi]);
1241
+ const filePickerApi = useMemo(() => createFilePickerApi(createFilePickerClient({ fetchClient: domainClient })), [domainClient]);
1242
+ const uiConfig = useMemo(() => ({
1243
+ user: userData ? {
1244
+ id: userData.id,
1245
+ company: userData.company ? { logo_url: userData.company.logo_url } : null
1246
+ } : void 0,
1247
+ affiliateId: userData?.affiliate_id ?? null,
1248
+ basePath: "",
1249
+ navigate: (path) => {
1250
+ const cleanPath = path.replace(/^\//, "");
1251
+ navigate(cleanPath.startsWith("share/") ? cleanPath : `share/${cleanPath}`);
1252
+ },
1253
+ showToast: (opts) => {
1254
+ console.warn(`[Shareables] ${opts.type}: ${opts.title}`);
1255
+ },
1256
+ filePickerApi,
1257
+ onToggleFavorite: async (params) => {
1258
+ const affiliateId = userData?.affiliate_id;
1259
+ if (!affiliateId) throw new Error("No affiliate ID");
1260
+ return domainClient.post(`/user_companies/${affiliateId}/favorites/toggle.json`, {
1261
+ favoriteable_id: params.favoriteableId,
1262
+ favoriteable_type: params.favoriteableType
1263
+ });
1264
+ },
1265
+ onDeletePlaylist: isCustomer ? void 0 : async (playlistId) => {
1266
+ await playlistsAdapter.deletePlaylist(playlistId);
1267
+ },
1268
+ readOnly: isCustomer
1269
+ }), [
1270
+ userData,
1271
+ navigate,
1272
+ filePickerApi,
1273
+ domainClient,
1274
+ isCustomer,
1275
+ playlistsAdapter
1276
+ ]);
1277
+ return /* @__PURE__ */ jsx("div", {
1278
+ ...divProps,
1279
+ className: `h-full ${divProps.className ?? ""}`,
1280
+ children: /* @__PURE__ */ jsx(ShareablesCoreProvider, {
1281
+ config: coreConfig,
1282
+ children: /* @__PURE__ */ jsx(ShareablesApiProvider, {
1283
+ api: shareablesApi,
1284
+ children: /* @__PURE__ */ jsx(ShareablesUIProvider, {
1285
+ config: uiConfig,
1286
+ children: /* @__PURE__ */ jsx(ShareablesApp, {
1287
+ screen,
1288
+ detailId,
1289
+ action,
1290
+ companyLogoUrl: userData?.company?.logo_url,
1291
+ countryCode: userData?.country?.iso,
1292
+ fetchProducts,
1293
+ fetchProduct,
1294
+ onNavigate: handleNavigate,
1295
+ onBack: handleBack
1296
+ })
1297
+ })
1298
+ })
1299
+ })
1300
+ });
1301
+ }
1302
+ const shareablesScreenPropertySchema = {
1303
+ widgetType: "ShareablesScreen",
1304
+ displayName: "Shareables Screen",
1305
+ tabsConfig: [{
1306
+ id: "styling",
1307
+ label: "Styling"
1308
+ }],
1309
+ fields: []
1310
+ };
1311
+ //#endregion
1312
+ export { shareablesScreenPropertySchema as n, useUserType as r, ShareablesScreen as t };
1313
+
1314
+ //# sourceMappingURL=ShareablesScreen-B6tMQzuX.mjs.map