{"version":3,"file":"prop-types-F7l9y7_B.mjs","names":["sdk.contentMediaByShares","sdk.contentMediaByVisits","sdk.contentPagesByShares","sdk.contentPagesByVisits","sdk.contentPlaylistsByShares","sdk.contentPlaylistsByVisits","sdk.damAssetPathsCreate","sdk.damAssetPathsList","sdk.damAssetsCreate","sdk.damAssetsDestroy","sdk.damAssetsDiscard","sdk.damAssetsList","sdk.favoritesToggle","sdk.mediaCreate","sdk.mediaDestroy","sdk.mediaList","sdk.mediaProductsAdd","sdk.mediaProductsList","sdk.mediaProductsRemove","sdk.mediaShow","sdk.mediaUpdate","sdk.pagesList","sdk.pagesShow","sdk.playlistsCreate","sdk.playlistsDestroy","sdk.playlistsItemsAdd","sdk.playlistsItemsList","sdk.playlistsItemsRemove","sdk.playlistsItemsReorder","sdk.playlistsList","sdk.playlistsShow","sdk.playlistsUpdate","sdk.sharesCreate","sdk.sharesList","portalTenantContent","portalTenant.enrollmentPacksList","portalTenant.enrollmentPacksShow"],"sources":["../../../api-clients/portal-tenant-content/src/hey-api/sdk.gen.ts","../src/adapters/portal-tenant-content-transport.ts","../../../api-clients/portal-tenant/src/hey-api/sdk.gen.ts","../src/providers/PortalTenantContentClientProvider.tsx","../src/providers/PortalTenantClientProvider.tsx","../../../shareables/core/src/context.tsx","../../../shareables/core/src/hooks/use-product-media-counts.ts","../../../shareables/core/src/hooks/use-media-mutations.ts","../../../shareables/core/src/utils.ts","../../../shareables/core/src/hooks/use-playlist-mutations.ts","../../../file-picker/core/src/file-picker-api-context.ts","../../../file-picker/core/src/schemas/dam.ts","../../../file-picker/core/src/utils/mime-type.ts","../../../file-picker/api-client/src/client.ts","../../../file-picker/api-client/src/api/dam-assets.ts","../../../file-picker/api-client/src/api/dam-query.ts","../../../file-picker/api-client/src/api/unsplash.ts","../../../file-picker/api-client/src/api/url-proxy.ts","../../../file-picker/api-client/src/create-file-picker-api.ts","../src/adapters/file-picker-api-adapter.ts","../../../shareables/core/src/favorites-api.ts","../src/adapters/content-api-adapter.ts","../src/content/PortalContentApiProvider.tsx","../../../../node_modules/.pnpm/prop-types@15.8.1/node_modules/prop-types/lib/ReactPropTypesSecret.js","../../../../node_modules/.pnpm/prop-types@15.8.1/node_modules/prop-types/factoryWithThrowingShims.js","../../../../node_modules/.pnpm/prop-types@15.8.1/node_modules/prop-types/index.js"],"sourcesContent":["// This file is auto-generated by @hey-api/openapi-ts\n\nimport type {\n  Client,\n  ClientMeta,\n  Options as Options2,\n  RequestResult,\n  TDataShape,\n} from \"@fluid-app/hey-api-fetch-runtime\";\n\nimport type {\n  ContentLanguagesListData,\n  ContentLanguagesListErrors,\n  ContentLanguagesListResponses,\n  ContentMediaBySharesData,\n  ContentMediaBySharesErrors,\n  ContentMediaBySharesResponses,\n  ContentMediaByVisitsData,\n  ContentMediaByVisitsErrors,\n  ContentMediaByVisitsResponses,\n  ContentPagesBySharesData,\n  ContentPagesBySharesErrors,\n  ContentPagesBySharesResponses,\n  ContentPagesByVisitsData,\n  ContentPagesByVisitsErrors,\n  ContentPagesByVisitsResponses,\n  ContentPlaylistsBySharesData,\n  ContentPlaylistsBySharesErrors,\n  ContentPlaylistsBySharesResponses,\n  ContentPlaylistsByVisitsData,\n  ContentPlaylistsByVisitsErrors,\n  ContentPlaylistsByVisitsResponses,\n  DamAssetPathsCreateData,\n  DamAssetPathsCreateErrors,\n  DamAssetPathsCreateResponses,\n  DamAssetPathsListData,\n  DamAssetPathsListErrors,\n  DamAssetPathsListResponses,\n  DamAssetsCreateData,\n  DamAssetsCreateErrors,\n  DamAssetsCreateResponses,\n  DamAssetsDestroyData,\n  DamAssetsDestroyErrors,\n  DamAssetsDestroyResponses,\n  DamAssetsDiscardData,\n  DamAssetsDiscardErrors,\n  DamAssetsDiscardResponses,\n  DamAssetsListData,\n  DamAssetsListErrors,\n  DamAssetsListResponses,\n  DamQueryData,\n  DamQueryErrors,\n  DamQueryResponses,\n  FavoritesToggleData,\n  FavoritesToggleErrors,\n  FavoritesToggleResponses,\n  MediaCreateData,\n  MediaCreateErrors,\n  MediaCreateResponses,\n  MediaDestroyData,\n  MediaDestroyErrors,\n  MediaDestroyResponses,\n  MediaListData,\n  MediaListErrors,\n  MediaListResponses,\n  MediaProductsAddData,\n  MediaProductsAddErrors,\n  MediaProductsAddResponses,\n  MediaProductsListData,\n  MediaProductsListErrors,\n  MediaProductsListResponses,\n  MediaProductsRemoveData,\n  MediaProductsRemoveErrors,\n  MediaProductsRemoveResponses,\n  MediaShowData,\n  MediaShowErrors,\n  MediaShowResponses,\n  MediaUpdateData,\n  MediaUpdateErrors,\n  MediaUpdateResponses,\n  PagesListData,\n  PagesListErrors,\n  PagesListResponses,\n  PagesShowData,\n  PagesShowErrors,\n  PagesShowResponses,\n  PlaylistsCreateData,\n  PlaylistsCreateErrors,\n  PlaylistsCreateResponses,\n  PlaylistsDestroyData,\n  PlaylistsDestroyErrors,\n  PlaylistsDestroyResponses,\n  PlaylistsItemsAddData,\n  PlaylistsItemsAddErrors,\n  PlaylistsItemsAddResponses,\n  PlaylistsItemsListData,\n  PlaylistsItemsListErrors,\n  PlaylistsItemsListResponses,\n  PlaylistsItemsRemoveData,\n  PlaylistsItemsRemoveErrors,\n  PlaylistsItemsRemoveResponses,\n  PlaylistsItemsReorderData,\n  PlaylistsItemsReorderErrors,\n  PlaylistsItemsReorderResponses,\n  PlaylistsListData,\n  PlaylistsListErrors,\n  PlaylistsListResponses,\n  PlaylistsShowData,\n  PlaylistsShowErrors,\n  PlaylistsShowResponses,\n  PlaylistsUpdateData,\n  PlaylistsUpdateErrors,\n  PlaylistsUpdateResponses,\n  SharesCreateData,\n  SharesCreateErrors,\n  SharesCreateResponses,\n  SharesListData,\n  SharesListErrors,\n  SharesListResponses,\n} from \"./types.gen\";\n\nexport type Options<\n  TData extends TDataShape = TDataShape,\n  ThrowOnError extends boolean = boolean,\n  TResponse = unknown,\n> = Options2<TData, ThrowOnError, TResponse> & {\n  /**\n   * You can provide a client instance returned by `createClient()` instead of\n   * individual options. This might be also useful if you want to implement a\n   * custom client.\n   */\n  client: Client;\n  /**\n   * You can pass arbitrary values through the `meta` object. This can be\n   * used to access values that aren't defined as part of the SDK function.\n   */\n  meta?: keyof ClientMeta extends never ? Record<string, unknown> : ClientMeta;\n};\n\n/**\n * List active languages for the tenant company\n *\n * Returns active languages enabled for the tenant company, sorted by name. Used by the content/translation editor to populate the language switcher.\n */\nexport const contentLanguagesList = <ThrowOnError extends boolean = true>(\n  options: Options<ContentLanguagesListData, ThrowOnError>,\n): RequestResult<\n  ContentLanguagesListResponses,\n  ContentLanguagesListErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    ContentLanguagesListResponses,\n    ContentLanguagesListErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/content/languages\",\n    ...options,\n  });\n\n/**\n * List media (own uploads and company share media)\n *\n * Returns a paginated list of the member's own uploads and company share media. Training and update media are excluded.\n */\nexport const mediaList = <ThrowOnError extends boolean = true>(\n  options: Options<MediaListData, ThrowOnError>,\n): RequestResult<MediaListResponses, MediaListErrors, ThrowOnError, \"data\"> =>\n  options.client.get<MediaListResponses, MediaListErrors, ThrowOnError, \"data\">(\n    {\n      responseStyle: \"data\",\n      security: [\n        {\n          in: \"cookie\",\n          name: \"portal_tenant_user_id\",\n          type: \"apiKey\",\n        },\n      ],\n      url: \"/api/content/media\",\n      ...options,\n    },\n  );\n\n/**\n * Create a new media item\n *\n * Creates a new media item record.\n */\nexport const mediaCreate = <ThrowOnError extends boolean = true>(\n  options: Options<MediaCreateData, ThrowOnError>,\n): RequestResult<\n  MediaCreateResponses,\n  MediaCreateErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.post<\n    MediaCreateResponses,\n    MediaCreateErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/content/media\",\n    ...options,\n    headers: {\n      \"Content-Type\": \"application/json\",\n      ...options.headers,\n    },\n  });\n\n/**\n * Delete a media item (own uploads only)\n *\n * Removes a media item.\n */\nexport const mediaDestroy = <ThrowOnError extends boolean = true>(\n  options: Options<MediaDestroyData, ThrowOnError>,\n): RequestResult<\n  MediaDestroyResponses,\n  MediaDestroyErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.delete<\n    MediaDestroyResponses,\n    MediaDestroyErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/content/media/{id}\",\n    ...options,\n  });\n\n/**\n * Get a specific media item\n *\n * Returns a single media item by ID. When language_iso is provided, translatable fields (title, description, url) are returned for that language with no fallback — empty values indicate an untranslated field.\n */\nexport const mediaShow = <ThrowOnError extends boolean = true>(\n  options: Options<MediaShowData, ThrowOnError>,\n): RequestResult<MediaShowResponses, MediaShowErrors, ThrowOnError, \"data\"> =>\n  options.client.get<MediaShowResponses, MediaShowErrors, ThrowOnError, \"data\">(\n    {\n      responseStyle: \"data\",\n      security: [\n        {\n          in: \"cookie\",\n          name: \"portal_tenant_user_id\",\n          type: \"apiKey\",\n        },\n      ],\n      url: \"/api/content/media/{id}\",\n      ...options,\n    },\n  );\n\n/**\n * Update a media item (own uploads only)\n *\n * Updates a media item's title, description, status, url, content_format, thumbnail, CTA, and SEO. When language_iso is provided, translatable fields are written against that language's translation row instead of the default locale.\n */\nexport const mediaUpdate = <ThrowOnError extends boolean = true>(\n  options: Options<MediaUpdateData, ThrowOnError>,\n): RequestResult<\n  MediaUpdateResponses,\n  MediaUpdateErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.patch<\n    MediaUpdateResponses,\n    MediaUpdateErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/content/media/{id}\",\n    ...options,\n    headers: {\n      \"Content-Type\": \"application/json\",\n      ...options.headers,\n    },\n  });\n\n/**\n * List products associated with a media item\n *\n * Returns a paginated list of products associated with a media item.\n */\nexport const mediaProductsList = <ThrowOnError extends boolean = true>(\n  options: Options<MediaProductsListData, ThrowOnError>,\n): RequestResult<\n  MediaProductsListResponses,\n  MediaProductsListErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    MediaProductsListResponses,\n    MediaProductsListErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/content/media/{medium_id}/products\",\n    ...options,\n  });\n\n/**\n * Associate a product with a media item\n *\n * Creates a product association for a media item.\n */\nexport const mediaProductsAdd = <ThrowOnError extends boolean = true>(\n  options: Options<MediaProductsAddData, ThrowOnError>,\n): RequestResult<\n  MediaProductsAddResponses,\n  MediaProductsAddErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.post<\n    MediaProductsAddResponses,\n    MediaProductsAddErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/content/media/{medium_id}/products\",\n    ...options,\n    headers: {\n      \"Content-Type\": \"application/json\",\n      ...options.headers,\n    },\n  });\n\n/**\n * Remove a product association from a media item\n *\n * Removes a single product association from a media item.\n */\nexport const mediaProductsRemove = <ThrowOnError extends boolean = true>(\n  options: Options<MediaProductsRemoveData, ThrowOnError>,\n): RequestResult<\n  MediaProductsRemoveResponses,\n  MediaProductsRemoveErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.delete<\n    MediaProductsRemoveResponses,\n    MediaProductsRemoveErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/content/media/{medium_id}/products/{id}\",\n    ...options,\n  });\n\n/**\n * List playlists with cursor pagination\n *\n * Returns a paginated list of playlists.\n */\nexport const playlistsList = <ThrowOnError extends boolean = true>(\n  options: Options<PlaylistsListData, ThrowOnError>,\n): RequestResult<\n  PlaylistsListResponses,\n  PlaylistsListErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    PlaylistsListResponses,\n    PlaylistsListErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/content/playlists\",\n    ...options,\n  });\n\n/**\n * Create a new playlist\n *\n * Creates a new playlist.\n */\nexport const playlistsCreate = <ThrowOnError extends boolean = true>(\n  options: Options<PlaylistsCreateData, ThrowOnError>,\n): RequestResult<\n  PlaylistsCreateResponses,\n  PlaylistsCreateErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.post<\n    PlaylistsCreateResponses,\n    PlaylistsCreateErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/content/playlists\",\n    ...options,\n    headers: {\n      \"Content-Type\": \"application/json\",\n      ...options.headers,\n    },\n  });\n\n/**\n * Delete a playlist\n *\n * Removes a playlist.\n */\nexport const playlistsDestroy = <ThrowOnError extends boolean = true>(\n  options: Options<PlaylistsDestroyData, ThrowOnError>,\n): RequestResult<\n  PlaylistsDestroyResponses,\n  PlaylistsDestroyErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.delete<\n    PlaylistsDestroyResponses,\n    PlaylistsDestroyErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/content/playlists/{id}\",\n    ...options,\n  });\n\n/**\n * Get a specific playlist\n *\n * Returns a single playlist by ID.\n */\nexport const playlistsShow = <ThrowOnError extends boolean = true>(\n  options: Options<PlaylistsShowData, ThrowOnError>,\n): RequestResult<\n  PlaylistsShowResponses,\n  PlaylistsShowErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    PlaylistsShowResponses,\n    PlaylistsShowErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/content/playlists/{id}\",\n    ...options,\n  });\n\n/**\n * Update a playlist\n *\n * Updates a playlist's title or metadata.\n */\nexport const playlistsUpdate = <ThrowOnError extends boolean = true>(\n  options: Options<PlaylistsUpdateData, ThrowOnError>,\n): RequestResult<\n  PlaylistsUpdateResponses,\n  PlaylistsUpdateErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.patch<\n    PlaylistsUpdateResponses,\n    PlaylistsUpdateErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/content/playlists/{id}\",\n    ...options,\n    headers: {\n      \"Content-Type\": \"application/json\",\n      ...options.headers,\n    },\n  });\n\n/**\n * List items in a playlist\n *\n * Returns a paginated list of items in a playlist.\n */\nexport const playlistsItemsList = <ThrowOnError extends boolean = true>(\n  options: Options<PlaylistsItemsListData, ThrowOnError>,\n): RequestResult<\n  PlaylistsItemsListResponses,\n  PlaylistsItemsListErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    PlaylistsItemsListResponses,\n    PlaylistsItemsListErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/content/playlists/{playlist_id}/items\",\n    ...options,\n  });\n\n/**\n * Add an item to a playlist\n *\n * Adds a content item (media, page, product, or enrollment_pack) to a playlist. Omit `position` to append the item to the end of the playlist. Returns 409 when the content is already in the playlist.\n */\nexport const playlistsItemsAdd = <ThrowOnError extends boolean = true>(\n  options: Options<PlaylistsItemsAddData, ThrowOnError>,\n): RequestResult<\n  PlaylistsItemsAddResponses,\n  PlaylistsItemsAddErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.post<\n    PlaylistsItemsAddResponses,\n    PlaylistsItemsAddErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/content/playlists/{playlist_id}/items\",\n    ...options,\n    headers: {\n      \"Content-Type\": \"application/json\",\n      ...options.headers,\n    },\n  });\n\n/**\n * Reorder items in a playlist\n *\n * Sets the order of items in a playlist. Items not included in the payload are not moved. Flips the playlist to manual ordering.\n */\nexport const playlistsItemsReorder = <ThrowOnError extends boolean = true>(\n  options: Options<PlaylistsItemsReorderData, ThrowOnError>,\n): RequestResult<\n  PlaylistsItemsReorderResponses,\n  PlaylistsItemsReorderErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.patch<\n    PlaylistsItemsReorderResponses,\n    PlaylistsItemsReorderErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/content/playlists/{playlist_id}/items/reorder\",\n    ...options,\n    headers: {\n      \"Content-Type\": \"application/json\",\n      ...options.headers,\n    },\n  });\n\n/**\n * Remove an item from a playlist\n *\n * Removes a single item from a playlist.\n */\nexport const playlistsItemsRemove = <ThrowOnError extends boolean = true>(\n  options: Options<PlaylistsItemsRemoveData, ThrowOnError>,\n): RequestResult<\n  PlaylistsItemsRemoveResponses,\n  PlaylistsItemsRemoveErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.delete<\n    PlaylistsItemsRemoveResponses,\n    PlaylistsItemsRemoveErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/content/playlists/{playlist_id}/items/{id}\",\n    ...options,\n  });\n\n/**\n * List pages for the company\n *\n * Returns a paginated list of published pages for the authenticated rep's company. Members have read-only access — there is no create, update, or destroy action for pages in the portal BFF. Response shape matches pages_show (PortalTenant::Api::PageBlueprinter).\n */\nexport const pagesList = <ThrowOnError extends boolean = true>(\n  options: Options<PagesListData, ThrowOnError>,\n): RequestResult<PagesListResponses, PagesListErrors, ThrowOnError, \"data\"> =>\n  options.client.get<PagesListResponses, PagesListErrors, ThrowOnError, \"data\">(\n    {\n      responseStyle: \"data\",\n      security: [\n        {\n          in: \"cookie\",\n          name: \"portal_tenant_user_id\",\n          type: \"apiKey\",\n        },\n      ],\n      url: \"/api/content/pages\",\n      ...options,\n    },\n  );\n\n/**\n * Get a specific page\n *\n * Returns a single page by ID, scoped to the authenticated rep's company. Response is a lean portal-BFF shape rendered by PortalTenant::Api::PageBlueprinter — not the legacy admin shape. Admin-only fields (html_code, application_theme_template, search_engine_optimizer, open_graph, prompts, etc.) are intentionally omitted.\n */\nexport const pagesShow = <ThrowOnError extends boolean = true>(\n  options: Options<PagesShowData, ThrowOnError>,\n): RequestResult<PagesShowResponses, PagesShowErrors, ThrowOnError, \"data\"> =>\n  options.client.get<PagesShowResponses, PagesShowErrors, ThrowOnError, \"data\">(\n    {\n      responseStyle: \"data\",\n      security: [\n        {\n          in: \"cookie\",\n          name: \"portal_tenant_user_id\",\n          type: \"apiKey\",\n        },\n      ],\n      url: \"/api/content/pages/{id}\",\n      ...options,\n    },\n  );\n\n/**\n * List share links for the current user\n *\n * Returns a paginated list of share links.\n */\nexport const sharesList = <ThrowOnError extends boolean = true>(\n  options: Options<SharesListData, ThrowOnError>,\n): RequestResult<SharesListResponses, SharesListErrors, ThrowOnError, \"data\"> =>\n  options.client.get<\n    SharesListResponses,\n    SharesListErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/shares\",\n    ...options,\n  });\n\n/**\n * Create a share link\n *\n * Creates a new share link for content.\n */\nexport const sharesCreate = <ThrowOnError extends boolean = true>(\n  options: Options<SharesCreateData, ThrowOnError>,\n): RequestResult<\n  SharesCreateResponses,\n  SharesCreateErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.post<\n    SharesCreateResponses,\n    SharesCreateErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/shares\",\n    ...options,\n    headers: {\n      \"Content-Type\": \"application/json\",\n      ...options.headers,\n    },\n  });\n\n/**\n * List DAM assets\n *\n * Returns a paginated list of DAM assets for the company.\n */\nexport const damAssetsList = <ThrowOnError extends boolean = true>(\n  options: Options<DamAssetsListData, ThrowOnError>,\n): RequestResult<\n  DamAssetsListResponses,\n  DamAssetsListErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    DamAssetsListResponses,\n    DamAssetsListErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/content/dam/assets\",\n    ...options,\n  });\n\n/**\n * Create a DAM asset\n *\n * Creates a new DAM asset. Supports two modes:\n * 1. **JSON placeholder** — send `application/json` with `asset[name]` to\n * create a placeholder record for later file upload.\n *\n * 2. **File upload** — send `multipart/form-data` with `asset[file]`,\n * `asset[name]`, and optionally `asset[description]` and `asset[tags]`\n * to upload a file and create the full asset with variants.\n */\nexport const damAssetsCreate = <ThrowOnError extends boolean = true>(\n  options: Options<DamAssetsCreateData, ThrowOnError>,\n): RequestResult<\n  DamAssetsCreateResponses,\n  DamAssetsCreateErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.post<\n    DamAssetsCreateResponses,\n    DamAssetsCreateErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/content/dam/assets\",\n    ...options,\n    headers: {\n      \"Content-Type\": \"application/json\",\n      ...options.headers,\n    },\n  });\n\n/**\n * List paths for a DAM asset\n *\n * Returns a paginated list of path aliases for a DAM asset.\n */\nexport const damAssetPathsList = <ThrowOnError extends boolean = true>(\n  options: Options<DamAssetPathsListData, ThrowOnError>,\n): RequestResult<\n  DamAssetPathsListResponses,\n  DamAssetPathsListErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    DamAssetPathsListResponses,\n    DamAssetPathsListErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/content/dam/assets/{asset_code}/paths\",\n    ...options,\n  });\n\n/**\n * Create a path alias for a DAM asset\n *\n * Creates a new path alias for an existing DAM asset.\n */\nexport const damAssetPathsCreate = <ThrowOnError extends boolean = true>(\n  options: Options<DamAssetPathsCreateData, ThrowOnError>,\n): RequestResult<\n  DamAssetPathsCreateResponses,\n  DamAssetPathsCreateErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.post<\n    DamAssetPathsCreateResponses,\n    DamAssetPathsCreateErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/content/dam/assets/{asset_code}/paths\",\n    ...options,\n    headers: {\n      \"Content-Type\": \"application/json\",\n      ...options.headers,\n    },\n  });\n\n/**\n * Query DAM assets using tree paths and tags\n *\n * Searches and retrieves DAM assets using tree path pattern matching, tag-based variant filtering, wildcard name matching, and partial search. Supports cursor pagination for large result sets.\n */\nexport const damQuery = <ThrowOnError extends boolean = true>(\n  options: Options<DamQueryData, ThrowOnError>,\n): RequestResult<DamQueryResponses, DamQueryErrors, ThrowOnError, \"data\"> =>\n  options.client.post<DamQueryResponses, DamQueryErrors, ThrowOnError, \"data\">({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/content/dam/query\",\n    ...options,\n    headers: {\n      \"Content-Type\": \"application/json\",\n      ...options.headers,\n    },\n  });\n\n/**\n * Delete a DAM asset\n *\n * Permanently destroys a DAM asset, including its ImageKit storage, variants, and database records.\n */\nexport const damAssetsDestroy = <ThrowOnError extends boolean = true>(\n  options: Options<DamAssetsDestroyData, ThrowOnError>,\n): RequestResult<\n  DamAssetsDestroyResponses,\n  DamAssetsDestroyErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.delete<\n    DamAssetsDestroyResponses,\n    DamAssetsDestroyErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/content/dam/assets/{code}\",\n    ...options,\n  });\n\n/**\n * Discard (soft-delete) a DAM asset\n *\n * Soft-deletes a DAM asset. Used to discard an in-progress upload without permanently removing the record.\n */\nexport const damAssetsDiscard = <ThrowOnError extends boolean = true>(\n  options: Options<DamAssetsDiscardData, ThrowOnError>,\n): RequestResult<\n  DamAssetsDiscardResponses,\n  DamAssetsDiscardErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.patch<\n    DamAssetsDiscardResponses,\n    DamAssetsDiscardErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/content/dam/assets/{code}/discard\",\n    ...options,\n  });\n\n/**\n * Toggle favorite status on a content item\n *\n * Toggles the favorite status of a content item for the authenticated member. If the item is not currently favorited, it becomes favorited. If it is already favorited, the favorite is removed.\n */\nexport const favoritesToggle = <ThrowOnError extends boolean = true>(\n  options: Options<FavoritesToggleData, ThrowOnError>,\n): RequestResult<\n  FavoritesToggleResponses,\n  FavoritesToggleErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.post<\n    FavoritesToggleResponses,\n    FavoritesToggleErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/content/favorites/toggle\",\n    ...options,\n    headers: {\n      \"Content-Type\": \"application/json\",\n      ...options.headers,\n    },\n  });\n\n/**\n * Top media by direct visits\n *\n * Ranked list of the company's media by total visits (aggregates metrics_media_visits across all visit sources).\n */\nexport const contentMediaByVisits = <ThrowOnError extends boolean = true>(\n  options: Options<ContentMediaByVisitsData, ThrowOnError>,\n): RequestResult<\n  ContentMediaByVisitsResponses,\n  ContentMediaByVisitsErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    ContentMediaByVisitsResponses,\n    ContentMediaByVisitsErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/content/media/by-visits\",\n    ...options,\n  });\n\n/**\n * Top media by share-link visits\n *\n * Ranked list of the company's media by click-throughs on rep share links (aggregates metrics_share_shareable_visits where shareable_type='Medium').\n */\nexport const contentMediaByShares = <ThrowOnError extends boolean = true>(\n  options: Options<ContentMediaBySharesData, ThrowOnError>,\n): RequestResult<\n  ContentMediaBySharesResponses,\n  ContentMediaBySharesErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    ContentMediaBySharesResponses,\n    ContentMediaBySharesErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/content/media/by-shares\",\n    ...options,\n  });\n\n/**\n * Top playlists by direct visits\n *\n * Ranked list of the company's playlists by total visits (aggregates metrics_library_visits since playlists are stored in the libraries table).\n */\nexport const contentPlaylistsByVisits = <ThrowOnError extends boolean = true>(\n  options: Options<ContentPlaylistsByVisitsData, ThrowOnError>,\n): RequestResult<\n  ContentPlaylistsByVisitsResponses,\n  ContentPlaylistsByVisitsErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    ContentPlaylistsByVisitsResponses,\n    ContentPlaylistsByVisitsErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/content/playlists/by-visits\",\n    ...options,\n  });\n\n/**\n * Top playlists by share-link visits\n *\n * Ranked list of the company's playlists by click-throughs on rep share links (aggregates metrics_share_shareable_visits where shareable_type='Library').\n */\nexport const contentPlaylistsByShares = <ThrowOnError extends boolean = true>(\n  options: Options<ContentPlaylistsBySharesData, ThrowOnError>,\n): RequestResult<\n  ContentPlaylistsBySharesResponses,\n  ContentPlaylistsBySharesErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    ContentPlaylistsBySharesResponses,\n    ContentPlaylistsBySharesErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/content/playlists/by-shares\",\n    ...options,\n  });\n\n/**\n * Top pages by direct visits\n *\n * Ranked list of the company's pages by total visits (aggregates metrics_page_visits across all visit sources).\n */\nexport const contentPagesByVisits = <ThrowOnError extends boolean = true>(\n  options: Options<ContentPagesByVisitsData, ThrowOnError>,\n): RequestResult<\n  ContentPagesByVisitsResponses,\n  ContentPagesByVisitsErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    ContentPagesByVisitsResponses,\n    ContentPagesByVisitsErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/content/pages/by-visits\",\n    ...options,\n  });\n\n/**\n * Top pages by share-link visits\n *\n * Ranked list of the company's pages by click-throughs on rep share links (aggregates metrics_share_shareable_visits where shareable_type='Page').\n */\nexport const contentPagesByShares = <ThrowOnError extends boolean = true>(\n  options: Options<ContentPagesBySharesData, ThrowOnError>,\n): RequestResult<\n  ContentPagesBySharesResponses,\n  ContentPagesBySharesErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    ContentPagesBySharesResponses,\n    ContentPagesBySharesErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    security: [\n      {\n        in: \"cookie\",\n        name: \"portal_tenant_user_id\",\n        type: \"apiKey\",\n      },\n    ],\n    url: \"/api/content/pages/by-shares\",\n    ...options,\n  });\n","import type { PortalTenantContentHeyApiClient } from \"@fluid-app/portal-tenant-content-api-client/client\";\nimport * as sdk from \"@fluid-app/portal-tenant-content-api-client/sdk\";\n\ntype OptionsOf<T> = T extends (options: infer Options) => unknown\n  ? Options\n  : never;\ntype QueryOf<T> = OptionsOf<T> extends { query?: infer Query } ? Query : never;\ntype BodyOf<T> = OptionsOf<T> extends { body: infer Body } ? Body : never;\ntype PathOf<T> = OptionsOf<T> extends { path: infer Path } ? Path : never;\n\nconst withQuery = <Query>(query: Query | undefined) =>\n  query === undefined ? {} : { query };\n\n/**\n * Consumer-owned call-shape adapter for the generated grouped Hey API SDK.\n * Domain adapters remain independent of generated transport option objects.\n */\nexport const portalTenantContentTransport = {\n  content_media_by_shares: (\n    client: PortalTenantContentHeyApiClient,\n    query?: QueryOf<typeof sdk.contentMediaByShares>,\n  ) => sdk.contentMediaByShares({ client, ...withQuery(query) }),\n  content_media_by_visits: (\n    client: PortalTenantContentHeyApiClient,\n    query?: QueryOf<typeof sdk.contentMediaByVisits>,\n  ) => sdk.contentMediaByVisits({ client, ...withQuery(query) }),\n  content_pages_by_shares: (\n    client: PortalTenantContentHeyApiClient,\n    query?: QueryOf<typeof sdk.contentPagesByShares>,\n  ) => sdk.contentPagesByShares({ client, ...withQuery(query) }),\n  content_pages_by_visits: (\n    client: PortalTenantContentHeyApiClient,\n    query?: QueryOf<typeof sdk.contentPagesByVisits>,\n  ) => sdk.contentPagesByVisits({ client, ...withQuery(query) }),\n  content_playlists_by_shares: (\n    client: PortalTenantContentHeyApiClient,\n    query?: QueryOf<typeof sdk.contentPlaylistsByShares>,\n  ) => sdk.contentPlaylistsByShares({ client, ...withQuery(query) }),\n  content_playlists_by_visits: (\n    client: PortalTenantContentHeyApiClient,\n    query?: QueryOf<typeof sdk.contentPlaylistsByVisits>,\n  ) => sdk.contentPlaylistsByVisits({ client, ...withQuery(query) }),\n  dam_asset_paths_create: (\n    client: PortalTenantContentHeyApiClient,\n    assetCode: PathOf<typeof sdk.damAssetPathsCreate>[\"asset_code\"],\n    body: BodyOf<typeof sdk.damAssetPathsCreate>,\n  ) =>\n    sdk.damAssetPathsCreate({\n      client,\n      path: { asset_code: assetCode },\n      body,\n    }),\n  dam_asset_paths_list: (\n    client: PortalTenantContentHeyApiClient,\n    assetCode: PathOf<typeof sdk.damAssetPathsList>[\"asset_code\"],\n    query?: QueryOf<typeof sdk.damAssetPathsList>,\n  ) =>\n    sdk.damAssetPathsList({\n      client,\n      path: { asset_code: assetCode },\n      ...withQuery(query),\n    }),\n  dam_assets_create: (\n    client: PortalTenantContentHeyApiClient,\n    body: BodyOf<typeof sdk.damAssetsCreate>,\n  ) => sdk.damAssetsCreate({ client, body }),\n  dam_assets_destroy: (\n    client: PortalTenantContentHeyApiClient,\n    assetCode: PathOf<typeof sdk.damAssetsDestroy>[\"code\"],\n  ) => sdk.damAssetsDestroy({ client, path: { code: assetCode } }),\n  dam_assets_discard: (\n    client: PortalTenantContentHeyApiClient,\n    assetCode: PathOf<typeof sdk.damAssetsDiscard>[\"code\"],\n  ) => sdk.damAssetsDiscard({ client, path: { code: assetCode } }),\n  dam_assets_list: (\n    client: PortalTenantContentHeyApiClient,\n    query?: QueryOf<typeof sdk.damAssetsList>,\n  ) => sdk.damAssetsList({ client, ...withQuery(query) }),\n  favorites_toggle: (\n    client: PortalTenantContentHeyApiClient,\n    body: BodyOf<typeof sdk.favoritesToggle>,\n  ) => sdk.favoritesToggle({ client, body }),\n  media_create: (\n    client: PortalTenantContentHeyApiClient,\n    body: BodyOf<typeof sdk.mediaCreate>,\n  ) => sdk.mediaCreate({ client, body }),\n  media_destroy: (\n    client: PortalTenantContentHeyApiClient,\n    id: PathOf<typeof sdk.mediaDestroy>[\"id\"],\n  ) => sdk.mediaDestroy({ client, path: { id } }),\n  media_list: (\n    client: PortalTenantContentHeyApiClient,\n    query?: QueryOf<typeof sdk.mediaList>,\n  ) => sdk.mediaList({ client, ...withQuery(query) }),\n  media_products_add: (\n    client: PortalTenantContentHeyApiClient,\n    mediumId: PathOf<typeof sdk.mediaProductsAdd>[\"medium_id\"],\n    body: BodyOf<typeof sdk.mediaProductsAdd>,\n  ) => sdk.mediaProductsAdd({ client, path: { medium_id: mediumId }, body }),\n  media_products_list: (\n    client: PortalTenantContentHeyApiClient,\n    mediumId: PathOf<typeof sdk.mediaProductsList>[\"medium_id\"],\n    query?: QueryOf<typeof sdk.mediaProductsList>,\n  ) =>\n    sdk.mediaProductsList({\n      client,\n      path: { medium_id: mediumId },\n      ...withQuery(query),\n    }),\n  media_products_remove: (\n    client: PortalTenantContentHeyApiClient,\n    mediumId: PathOf<typeof sdk.mediaProductsRemove>[\"medium_id\"],\n    id: PathOf<typeof sdk.mediaProductsRemove>[\"id\"],\n  ) =>\n    sdk.mediaProductsRemove({\n      client,\n      path: { medium_id: mediumId, id },\n    }),\n  media_show: (\n    client: PortalTenantContentHeyApiClient,\n    id: PathOf<typeof sdk.mediaShow>[\"id\"],\n    query?: QueryOf<typeof sdk.mediaShow>,\n  ) => sdk.mediaShow({ client, path: { id }, ...withQuery(query) }),\n  media_update: (\n    client: PortalTenantContentHeyApiClient,\n    id: PathOf<typeof sdk.mediaUpdate>[\"id\"],\n    body: BodyOf<typeof sdk.mediaUpdate>,\n    query?: QueryOf<typeof sdk.mediaUpdate>,\n  ) => sdk.mediaUpdate({ client, path: { id }, body, ...withQuery(query) }),\n  pages_list: (\n    client: PortalTenantContentHeyApiClient,\n    query?: QueryOf<typeof sdk.pagesList>,\n  ) => sdk.pagesList({ client, ...withQuery(query) }),\n  pages_show: (\n    client: PortalTenantContentHeyApiClient,\n    id: PathOf<typeof sdk.pagesShow>[\"id\"],\n    query?: QueryOf<typeof sdk.pagesShow>,\n  ) => sdk.pagesShow({ client, path: { id }, ...withQuery(query) }),\n  playlists_create: (\n    client: PortalTenantContentHeyApiClient,\n    body: BodyOf<typeof sdk.playlistsCreate>,\n  ) => sdk.playlistsCreate({ client, body }),\n  playlists_destroy: (\n    client: PortalTenantContentHeyApiClient,\n    id: PathOf<typeof sdk.playlistsDestroy>[\"id\"],\n  ) => sdk.playlistsDestroy({ client, path: { id } }),\n  playlists_items_add: (\n    client: PortalTenantContentHeyApiClient,\n    playlistId: PathOf<typeof sdk.playlistsItemsAdd>[\"playlist_id\"],\n    body: BodyOf<typeof sdk.playlistsItemsAdd>,\n  ) =>\n    sdk.playlistsItemsAdd({\n      client,\n      path: { playlist_id: playlistId },\n      body,\n    }),\n  playlists_items_list: (\n    client: PortalTenantContentHeyApiClient,\n    playlistId: PathOf<typeof sdk.playlistsItemsList>[\"playlist_id\"],\n    query?: QueryOf<typeof sdk.playlistsItemsList>,\n  ) =>\n    sdk.playlistsItemsList({\n      client,\n      path: { playlist_id: playlistId },\n      ...withQuery(query),\n    }),\n  playlists_items_remove: (\n    client: PortalTenantContentHeyApiClient,\n    playlistId: PathOf<typeof sdk.playlistsItemsRemove>[\"playlist_id\"],\n    id: PathOf<typeof sdk.playlistsItemsRemove>[\"id\"],\n  ) =>\n    sdk.playlistsItemsRemove({\n      client,\n      path: { playlist_id: playlistId, id },\n    }),\n  playlists_items_reorder: (\n    client: PortalTenantContentHeyApiClient,\n    playlistId: PathOf<typeof sdk.playlistsItemsReorder>[\"playlist_id\"],\n    body: BodyOf<typeof sdk.playlistsItemsReorder>,\n  ) =>\n    sdk.playlistsItemsReorder({\n      client,\n      path: { playlist_id: playlistId },\n      body,\n    }),\n  playlists_list: (\n    client: PortalTenantContentHeyApiClient,\n    query?: QueryOf<typeof sdk.playlistsList>,\n  ) => sdk.playlistsList({ client, ...withQuery(query) }),\n  playlists_show: (\n    client: PortalTenantContentHeyApiClient,\n    id: PathOf<typeof sdk.playlistsShow>[\"id\"],\n  ) => sdk.playlistsShow({ client, path: { id } }),\n  playlists_update: (\n    client: PortalTenantContentHeyApiClient,\n    id: PathOf<typeof sdk.playlistsUpdate>[\"id\"],\n    body: BodyOf<typeof sdk.playlistsUpdate>,\n  ) => sdk.playlistsUpdate({ client, path: { id }, body }),\n  shares_create: (\n    client: PortalTenantContentHeyApiClient,\n    body: BodyOf<typeof sdk.sharesCreate>,\n  ) => sdk.sharesCreate({ client, body }),\n  shares_list: (\n    client: PortalTenantContentHeyApiClient,\n    query?: QueryOf<typeof sdk.sharesList>,\n  ) => sdk.sharesList({ client, ...withQuery(query) }),\n} as const;\n","// This file is auto-generated by @hey-api/openapi-ts\n\nimport type {\n  Client,\n  ClientMeta,\n  Options as Options2,\n  RequestResult,\n  TDataShape,\n} from \"@fluid-app/hey-api-fetch-runtime\";\n\nimport type {\n  AccountEmbedTokenCreateData,\n  AccountEmbedTokenCreateErrors,\n  AccountEmbedTokenCreateResponses,\n  AccountShowData,\n  AccountShowErrors,\n  AccountShowResponses,\n  AccountUpdateData,\n  AccountUpdateErrors,\n  AccountUpdateResponses,\n  ActivitiesListData,\n  ActivitiesListErrors,\n  ActivitiesListResponses,\n  ActivitiesReadData,\n  ActivitiesReadErrors,\n  ActivitiesReadResponses,\n  AddressFieldsShowData,\n  AddressFieldsShowErrors,\n  AddressFieldsShowResponses,\n  AppManifestShowData,\n  AppManifestShowErrors,\n  AppManifestShowResponses,\n  AppWidgetPackagesListData,\n  AppWidgetPackagesListErrors,\n  AppWidgetPackagesListResponses,\n  CalendarEventsListData,\n  CalendarEventsListErrors,\n  CalendarEventsListResponses,\n  CartsClaimData,\n  CartsClaimErrors,\n  CartsClaimResponses,\n  CatchUpActionsDismissData,\n  CatchUpActionsDismissErrors,\n  CatchUpActionsDismissResponses,\n  CatchUpsListData,\n  CatchUpsListErrors,\n  CatchUpsListResponses,\n  CatchUpsShowData,\n  CatchUpsShowErrors,\n  CatchUpsShowResponses,\n  EnrollmentPackBySharesData,\n  EnrollmentPackBySharesErrors,\n  EnrollmentPackBySharesResponses,\n  EnrollmentPackByVisitsData,\n  EnrollmentPackByVisitsErrors,\n  EnrollmentPackByVisitsResponses,\n  EnrollmentPacksListData,\n  EnrollmentPacksListErrors,\n  EnrollmentPacksListResponses,\n  EnrollmentPacksShowData,\n  EnrollmentPacksShowErrors,\n  EnrollmentPacksShowResponses,\n  OrdersListData,\n  OrdersListErrors,\n  OrdersListResponses,\n  OrdersShowData,\n  OrdersShowErrors,\n  OrdersShowResponses,\n  ProductBySharesData,\n  ProductBySharesErrors,\n  ProductBySharesResponses,\n  ProductByVisitsData,\n  ProductByVisitsErrors,\n  ProductByVisitsResponses,\n  ProductsListData,\n  ProductsListErrors,\n  ProductsListResponses,\n  ProductsMediaListData,\n  ProductsMediaListErrors,\n  ProductsMediaListResponses,\n  ProductsSearchData,\n  ProductsSearchErrors,\n  ProductsSearchResponses,\n  ProductsShowData,\n  ProductsShowErrors,\n  ProductsShowResponses,\n  StoreShowData,\n  StoreShowErrors,\n  StoreShowResponses,\n  SubscriptionBundlesCreateData,\n  SubscriptionBundlesCreateErrors,\n  SubscriptionBundlesCreateResponses,\n  SubscriptionBundlesListData,\n  SubscriptionBundlesListErrors,\n  SubscriptionBundlesListResponses,\n  SubscriptionDiscountsAttachData,\n  SubscriptionDiscountsAttachErrors,\n  SubscriptionDiscountsAttachResponses,\n  SubscriptionDiscountsListData,\n  SubscriptionDiscountsListErrors,\n  SubscriptionDiscountsListResponses,\n  SubscriptionDiscountsRemoveData,\n  SubscriptionDiscountsRemoveErrors,\n  SubscriptionDiscountsRemoveResponses,\n  SubscriptionsCancelData,\n  SubscriptionsCancelErrors,\n  SubscriptionsCancelResponses,\n  SubscriptionsFailedCycleWaiverCreateData,\n  SubscriptionsFailedCycleWaiverCreateErrors,\n  SubscriptionsFailedCycleWaiverCreateResponses,\n  SubscriptionsFailedCycleWaiverPreviewData,\n  SubscriptionsFailedCycleWaiverPreviewErrors,\n  SubscriptionsFailedCycleWaiverPreviewResponses,\n  SubscriptionsListData,\n  SubscriptionsListErrors,\n  SubscriptionsListResponses,\n  SubscriptionsPauseData,\n  SubscriptionsPauseErrors,\n  SubscriptionsPauseResponses,\n  SubscriptionsReactivateData,\n  SubscriptionsReactivateErrors,\n  SubscriptionsReactivateResponses,\n  SubscriptionsResumeData,\n  SubscriptionsResumeErrors,\n  SubscriptionsResumeResponses,\n  SubscriptionsRetryData,\n  SubscriptionsRetryErrors,\n  SubscriptionsRetryResponses,\n  SubscriptionsShowData,\n  SubscriptionsShowErrors,\n  SubscriptionsShowResponses,\n  SubscriptionsSkipData,\n  SubscriptionsSkipErrors,\n  SubscriptionsSkipResponses,\n  SubscriptionsUpdateData,\n  SubscriptionsUpdateErrors,\n  SubscriptionsUpdateResponses,\n  TodosCreateData,\n  TodosCreateErrors,\n  TodosCreateResponses,\n  TodosDestroyData,\n  TodosDestroyErrors,\n  TodosDestroyResponses,\n  TodosListData,\n  TodosListErrors,\n  TodosListResponses,\n  TodosUpdateData,\n  TodosUpdateErrors,\n  TodosUpdateResponses,\n} from \"./types.gen\";\n\nexport type Options<\n  TData extends TDataShape = TDataShape,\n  ThrowOnError extends boolean = boolean,\n  TResponse = unknown,\n> = Options2<TData, ThrowOnError, TResponse> & {\n  /**\n   * You can provide a client instance returned by `createClient()` instead of\n   * individual options. This might be also useful if you want to implement a\n   * custom client.\n   */\n  client: Client;\n  /**\n   * You can pass arbitrary values through the `meta` object. This can be\n   * used to access values that aren't defined as part of the SDK function.\n   */\n  meta?: keyof ClientMeta extends never ? Record<string, unknown> : ClientMeta;\n};\n\n/**\n * Get address fields for a country\n *\n * Returns the address field configuration for a given country code, including field names, localized labels, and whether each field is required. Use the optional language_iso query parameter to receive labels in a specific locale; defaults to English.\n */\nexport const addressFieldsShow = <ThrowOnError extends boolean = true>(\n  options: Options<AddressFieldsShowData, ThrowOnError>,\n): RequestResult<\n  AddressFieldsShowResponses,\n  AddressFieldsShowErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    AddressFieldsShowResponses,\n    AddressFieldsShowErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/countries/{country_code}/address_fields\",\n    ...options,\n  });\n\n/**\n * Issue an embed context token\n *\n * Returns a short-lived signed token the Portal appends to an embed iframe so the embedded page can trust which member is viewing it.\n *\n * The token names the origin of the supplied `embed_url` and carries no API authority — it asserts identity and nothing else, which is what makes it safe to hand to a third-party page. It is not an authentication token and cannot be used as a bearer against this API.\n *\n * Signed with RS256. The public verification key is published as a JWK Set at `/.well-known/portal-embed-jwks.json` on the same host, so a consumer can verify a token without being able to mint one. Consumers must pin `aud` to their own origin and `iss` to the expected Portal host.\n */\nexport const accountEmbedTokenCreate = <ThrowOnError extends boolean = true>(\n  options: Options<AccountEmbedTokenCreateData, ThrowOnError>,\n): RequestResult<\n  AccountEmbedTokenCreateResponses,\n  AccountEmbedTokenCreateErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.post<\n    AccountEmbedTokenCreateResponses,\n    AccountEmbedTokenCreateErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/account/embed_token\",\n    ...options,\n    headers: {\n      \"Content-Type\": \"application/json\",\n      ...options.headers,\n    },\n  });\n\n/**\n * Get current account\n *\n * Returns the authenticated member's account profile and company context. This is the primary endpoint the SPA calls to check auth status and display user information.\n */\nexport const accountShow = <ThrowOnError extends boolean = true>(\n  options: Options<AccountShowData, ThrowOnError>,\n): RequestResult<\n  AccountShowResponses,\n  AccountShowErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    AccountShowResponses,\n    AccountShowErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/account\",\n    ...options,\n  });\n\n/**\n * Update current account\n *\n * Updates the authenticated member's profile fields such as name, phone, bio, avatar, and social links.\n */\nexport const accountUpdate = <ThrowOnError extends boolean = true>(\n  options: Options<AccountUpdateData, ThrowOnError>,\n): RequestResult<\n  AccountUpdateResponses,\n  AccountUpdateErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.patch<\n    AccountUpdateResponses,\n    AccountUpdateErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/account\",\n    ...options,\n    headers: {\n      \"Content-Type\": \"application/json\",\n      ...options.headers,\n    },\n  });\n\n/**\n * Get store branding and feature flags\n *\n * Returns the tenant company's store branding (logo, icon, app store URLs) and feature flags such as whether subscription bundling is enabled.\n */\nexport const storeShow = <ThrowOnError extends boolean = true>(\n  options: Options<StoreShowData, ThrowOnError>,\n): RequestResult<StoreShowResponses, StoreShowErrors, ThrowOnError, \"data\"> =>\n  options.client.get<StoreShowResponses, StoreShowErrors, ThrowOnError, \"data\">(\n    {\n      responseStyle: \"data\",\n      url: \"/api/store\",\n      ...options,\n    },\n  );\n\n/**\n * Get the app manifest\n *\n * Returns the rendered manifest for the tenant company's active FluidOS definition and version, matched against the current user's country, rank, and roles.\n */\nexport const appManifestShow = <ThrowOnError extends boolean = true>(\n  options: Options<AppManifestShowData, ThrowOnError>,\n): RequestResult<\n  AppManifestShowResponses,\n  AppManifestShowErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    AppManifestShowResponses,\n    AppManifestShowErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/app/manifest\",\n    ...options,\n  });\n\n/**\n * List widget packages\n *\n * Returns approved active portal widget packages for the tenant company. Company-owned packages are returned before approved packages from active installed droplets so the portal shell can load widgets in order.\n */\nexport const appWidgetPackagesList = <ThrowOnError extends boolean = true>(\n  options: Options<AppWidgetPackagesListData, ThrowOnError>,\n): RequestResult<\n  AppWidgetPackagesListResponses,\n  AppWidgetPackagesListErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    AppWidgetPackagesListResponses,\n    AppWidgetPackagesListErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/app/widget-packages\",\n    ...options,\n  });\n\n/**\n * List calendar events\n *\n * Returns a paginated list of upcoming and ongoing calendar events for the tenant company, optionally filtered by the authenticated member's country when one is set.\n */\nexport const calendarEventsList = <ThrowOnError extends boolean = true>(\n  options: Options<CalendarEventsListData, ThrowOnError>,\n): RequestResult<\n  CalendarEventsListResponses,\n  CalendarEventsListErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    CalendarEventsListResponses,\n    CalendarEventsListErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/calendar/events\",\n    ...options,\n  });\n\n/**\n * List recent activities\n *\n * Returns a paginated list of recent activities for the authenticated member, ordered by most recent first. Each activity includes pre-computed user_name and target_name fields ready for direct rendering by the portal SPA, plus a slug-dependent `details` object for richer per-type cards. When `days_ago` is provided, the response is restricted to that rolling window and `meta.pagination.total_count` is populated.\n */\nexport const activitiesList = <ThrowOnError extends boolean = true>(\n  options: Options<ActivitiesListData, ThrowOnError>,\n): RequestResult<\n  ActivitiesListResponses,\n  ActivitiesListErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    ActivitiesListResponses,\n    ActivitiesListErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/activities\",\n    ...options,\n  });\n\n/**\n * Mark activities as read\n *\n * Marks every unread activity in the authenticated member's feed as read, and refreshes their unread activity counter. Takes no parameters, and affects exactly the rows `activities_list` returns without filters, so a member can never mark anything they cannot see. Calling it again marks nothing and reports zero.\n */\nexport const activitiesRead = <ThrowOnError extends boolean = true>(\n  options: Options<ActivitiesReadData, ThrowOnError>,\n): RequestResult<\n  ActivitiesReadResponses,\n  ActivitiesReadErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.post<\n    ActivitiesReadResponses,\n    ActivitiesReadErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/activities/read\",\n    ...options,\n  });\n\n/**\n * List catch-up suggestions\n *\n * Returns a paginated list of catch-up suggestions for the authenticated member. Limited to suggestions with at least one pending action that have not expired.\n */\nexport const catchUpsList = <ThrowOnError extends boolean = true>(\n  options: Options<CatchUpsListData, ThrowOnError>,\n): RequestResult<\n  CatchUpsListResponses,\n  CatchUpsListErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    CatchUpsListResponses,\n    CatchUpsListErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/catch_ups\",\n    ...options,\n  });\n\n/**\n * Get a catch-up suggestion\n *\n * Returns a single catch-up suggestion by id, scoped to the authenticated member. Returns 404 when the catch-up belongs to a different member.\n */\nexport const catchUpsShow = <ThrowOnError extends boolean = true>(\n  options: Options<CatchUpsShowData, ThrowOnError>,\n): RequestResult<\n  CatchUpsShowResponses,\n  CatchUpsShowErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    CatchUpsShowResponses,\n    CatchUpsShowErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/catch_ups/{id}\",\n    ...options,\n  });\n\n/**\n * Dismiss a catch-up action\n *\n * Marks a catch-up action as read (resolved), scoped to the authenticated\n * member. Idempotent — dismissing an already-resolved action succeeds and\n * no-ops. Returns 404 when the parent catch-up belongs to a different\n * member or has expired, or when the action does not belong to it.\n *\n */\nexport const catchUpActionsDismiss = <ThrowOnError extends boolean = true>(\n  options: Options<CatchUpActionsDismissData, ThrowOnError>,\n): RequestResult<\n  CatchUpActionsDismissResponses,\n  CatchUpActionsDismissErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.post<\n    CatchUpActionsDismissResponses,\n    CatchUpActionsDismissErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/catch_ups/{catch_up_id}/catch_up_actions/{id}/dismiss\",\n    ...options,\n  });\n\n/**\n * List orders\n *\n * Returns a paginated list of orders placed through the tenant company, optionally filtered by status.\n */\nexport const ordersList = <ThrowOnError extends boolean = true>(\n  options: Options<OrdersListData, ThrowOnError>,\n): RequestResult<OrdersListResponses, OrdersListErrors, ThrowOnError, \"data\"> =>\n  options.client.get<\n    OrdersListResponses,\n    OrdersListErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/orders\",\n    ...options,\n  });\n\n/**\n * Get an order\n *\n * Returns a single order by token with its line items.\n */\nexport const ordersShow = <ThrowOnError extends boolean = true>(\n  options: Options<OrdersShowData, ThrowOnError>,\n): RequestResult<OrdersShowResponses, OrdersShowErrors, ThrowOnError, \"data\"> =>\n  options.client.get<\n    OrdersShowResponses,\n    OrdersShowErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/orders/{token}\",\n    ...options,\n  });\n\n/**\n * List products\n *\n * Returns a paginated list of products available in the tenant company's catalog. Supports sorting and filtering by title, product type, collection, and stock availability.\n */\nexport const productsList = <ThrowOnError extends boolean = true>(\n  options: Options<ProductsListData, ThrowOnError>,\n): RequestResult<\n  ProductsListResponses,\n  ProductsListErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    ProductsListResponses,\n    ProductsListErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/products\",\n    ...options,\n  });\n\n/**\n * Get a product\n *\n * Returns a single product by ID with its variants.\n */\nexport const productsShow = <ThrowOnError extends boolean = true>(\n  options: Options<ProductsShowData, ThrowOnError>,\n): RequestResult<\n  ProductsShowResponses,\n  ProductsShowErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    ProductsShowResponses,\n    ProductsShowErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/products/{id}\",\n    ...options,\n  });\n\n/**\n * Search products\n *\n * Searches the tenant company's product catalog by keyword, returning paginated results.\n */\nexport const productsSearch = <ThrowOnError extends boolean = true>(\n  options: Options<ProductsSearchData, ThrowOnError>,\n): RequestResult<\n  ProductsSearchResponses,\n  ProductsSearchErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    ProductsSearchResponses,\n    ProductsSearchErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/products/search\",\n    ...options,\n  });\n\n/**\n * List product media\n *\n * Returns all media (images, videos) attached to a product.\n */\nexport const productsMediaList = <ThrowOnError extends boolean = true>(\n  options: Options<ProductsMediaListData, ThrowOnError>,\n): RequestResult<\n  ProductsMediaListResponses,\n  ProductsMediaListErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    ProductsMediaListResponses,\n    ProductsMediaListErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/products/{id}/media\",\n    ...options,\n  });\n\n/**\n * List enrollment packs\n *\n * Returns a paginated list of active, non-discarded enrollment packs scoped to the current portal tenant's company. Each pack carries an empty `products` array — fetch a single pack via `/api/enrollment_packs/{id}` to load its visible products.\n */\nexport const enrollmentPacksList = <ThrowOnError extends boolean = true>(\n  options: Options<EnrollmentPacksListData, ThrowOnError>,\n): RequestResult<\n  EnrollmentPacksListResponses,\n  EnrollmentPacksListErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    EnrollmentPacksListResponses,\n    EnrollmentPacksListErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/enrollment_packs\",\n    ...options,\n  });\n\n/**\n * Get an enrollment pack\n *\n * Returns a single active, non-discarded enrollment pack scoped to the current portal tenant's company.\n */\nexport const enrollmentPacksShow = <ThrowOnError extends boolean = true>(\n  options: Options<EnrollmentPacksShowData, ThrowOnError>,\n): RequestResult<\n  EnrollmentPacksShowResponses,\n  EnrollmentPacksShowErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    EnrollmentPacksShowResponses,\n    EnrollmentPacksShowErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/enrollment_packs/{id}\",\n    ...options,\n  });\n\n/**\n * List subscription bundles\n *\n * Returns the runtime bundle groupings for the authenticated customer's active subscriptions. Bundles are computed at request time by grouping subscriptions that share customer, address (physical only), volume rep, next bill date, and digital flag — they have no persistent id. The response is unpaginated; customers typically have a small number of bundles.\n */\nexport const subscriptionBundlesList = <ThrowOnError extends boolean = true>(\n  options: Options<SubscriptionBundlesListData, ThrowOnError>,\n): RequestResult<\n  SubscriptionBundlesListResponses,\n  SubscriptionBundlesListErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    SubscriptionBundlesListResponses,\n    SubscriptionBundlesListErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/subscription_bundles\",\n    ...options,\n  });\n\n/**\n * List subscriptions\n *\n * Returns a paginated list of the member's active and historical subscriptions. Supports filtering by lifecycle state and a free-text search across product and plan names.\n */\nexport const subscriptionsList = <ThrowOnError extends boolean = true>(\n  options: Options<SubscriptionsListData, ThrowOnError>,\n): RequestResult<\n  SubscriptionsListResponses,\n  SubscriptionsListErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    SubscriptionsListResponses,\n    SubscriptionsListErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/subscriptions\",\n    ...options,\n  });\n\n/**\n * Get a subscription\n *\n * Returns a single subscription by its token.\n */\nexport const subscriptionsShow = <ThrowOnError extends boolean = true>(\n  options: Options<SubscriptionsShowData, ThrowOnError>,\n): RequestResult<\n  SubscriptionsShowResponses,\n  SubscriptionsShowErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    SubscriptionsShowResponses,\n    SubscriptionsShowErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/subscriptions/{token}\",\n    ...options,\n  });\n\n/**\n * Update a subscription\n *\n * Updates a subscription's default payment method, quantity, address, next billing date, or reward-points opt-in. Rearming a billable subscription returns 422 when the current plan's maximum successful billing-cycle limit is reached or invalid. An auto_apply_points write may be scoped to the whole renewal bundle, in which case it is applied to every member atomically and returns 409 if membership shifts under it.\n */\nexport const subscriptionsUpdate = <ThrowOnError extends boolean = true>(\n  options: Options<SubscriptionsUpdateData, ThrowOnError>,\n): RequestResult<\n  SubscriptionsUpdateResponses,\n  SubscriptionsUpdateErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.put<\n    SubscriptionsUpdateResponses,\n    SubscriptionsUpdateErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/subscriptions/{token}\",\n    ...options,\n    headers: {\n      \"Content-Type\": \"application/json\",\n      ...options.headers,\n    },\n  });\n\n/**\n * List subscription discounts\n *\n * Returns active and historical discount attachments for a visible subscription, newest first.\n */\nexport const subscriptionDiscountsList = <ThrowOnError extends boolean = true>(\n  options: Options<SubscriptionDiscountsListData, ThrowOnError>,\n): RequestResult<\n  SubscriptionDiscountsListResponses,\n  SubscriptionDiscountsListErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    SubscriptionDiscountsListResponses,\n    SubscriptionDiscountsListErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/subscriptions/{token}/discounts\",\n    ...options,\n  });\n\n/**\n * Attach a subscription discount\n *\n * Attaches an eligible discount to a visible subscription.\n */\nexport const subscriptionDiscountsAttach = <\n  ThrowOnError extends boolean = true,\n>(\n  options: Options<SubscriptionDiscountsAttachData, ThrowOnError>,\n): RequestResult<\n  SubscriptionDiscountsAttachResponses,\n  SubscriptionDiscountsAttachErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.post<\n    SubscriptionDiscountsAttachResponses,\n    SubscriptionDiscountsAttachErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/subscriptions/{token}/discounts\",\n    ...options,\n    headers: {\n      \"Content-Type\": \"application/json\",\n      ...options.headers,\n    },\n  });\n\n/**\n * Remove a subscription discount\n *\n * Soft-removes a visible subscription discount attachment.\n */\nexport const subscriptionDiscountsRemove = <\n  ThrowOnError extends boolean = true,\n>(\n  options: Options<SubscriptionDiscountsRemoveData, ThrowOnError>,\n): RequestResult<\n  SubscriptionDiscountsRemoveResponses,\n  SubscriptionDiscountsRemoveErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.delete<\n    SubscriptionDiscountsRemoveResponses,\n    SubscriptionDiscountsRemoveErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/subscriptions/{token}/discounts/{id}\",\n    ...options,\n    headers: {\n      \"Content-Type\": \"application/json\",\n      ...options.headers,\n    },\n  });\n\n/**\n * Pause a subscription\n *\n * Pauses billing on an active subscription. When neither `next_bill_date` nor `number_of_orders` is provided, the subscription is paused indefinitely. Specifying both is rejected.\n */\nexport const subscriptionsPause = <ThrowOnError extends boolean = true>(\n  options: Options<SubscriptionsPauseData, ThrowOnError>,\n): RequestResult<\n  SubscriptionsPauseResponses,\n  SubscriptionsPauseErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.post<\n    SubscriptionsPauseResponses,\n    SubscriptionsPauseErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/subscriptions/{token}/pause\",\n    ...options,\n    headers: {\n      \"Content-Type\": \"application/json\",\n      ...options.headers,\n    },\n  });\n\n/**\n * Resume a subscription\n *\n * Resumes billing on a paused subscription or restores normal scheduled billing for an exhausted past-due subscription without charging immediately. Paused subscriptions use the supplied next bill date, or the plan's next date when omitted. Exhausted subscriptions preserve a future bill date; a stale date is moved into the future using the subscription plan cadence. Returns 422 when the current plan's maximum successful billing-cycle limit has been reached.\n */\nexport const subscriptionsResume = <ThrowOnError extends boolean = true>(\n  options: Options<SubscriptionsResumeData, ThrowOnError>,\n): RequestResult<\n  SubscriptionsResumeResponses,\n  SubscriptionsResumeErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.post<\n    SubscriptionsResumeResponses,\n    SubscriptionsResumeErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/subscriptions/{token}/resume\",\n    ...options,\n    headers: {\n      \"Content-Type\": \"application/json\",\n      ...options.headers,\n    },\n  });\n\n/**\n * Preview a failed-cycle waiver\n *\n * Returns the authoritative future billing and shipping timestamps that would be restored if the exhausted failed cycle were waived. An ineligible subscription returns 200 with eligible false and null dates.\n */\nexport const subscriptionsFailedCycleWaiverPreview = <\n  ThrowOnError extends boolean = true,\n>(\n  options: Options<SubscriptionsFailedCycleWaiverPreviewData, ThrowOnError>,\n): RequestResult<\n  SubscriptionsFailedCycleWaiverPreviewResponses,\n  SubscriptionsFailedCycleWaiverPreviewErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    SubscriptionsFailedCycleWaiverPreviewResponses,\n    SubscriptionsFailedCycleWaiverPreviewErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/subscriptions/{token}/failed-cycle-waiver\",\n    ...options,\n  });\n\n/**\n * Skip the exhausted failed cycle\n *\n * Waives the missed billing and shipping cycle without collecting payment and without creating an order or shipment. The missed shipment is skipped. The subscription's original billing and shipping cadence and anchors are preserved, and each stored next date is advanced independently only as needed to reach a future local date. Returns 422 when the current plan's maximum successful billing-cycle limit has been reached.\n */\nexport const subscriptionsFailedCycleWaiverCreate = <\n  ThrowOnError extends boolean = true,\n>(\n  options: Options<SubscriptionsFailedCycleWaiverCreateData, ThrowOnError>,\n): RequestResult<\n  SubscriptionsFailedCycleWaiverCreateResponses,\n  SubscriptionsFailedCycleWaiverCreateErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.post<\n    SubscriptionsFailedCycleWaiverCreateResponses,\n    SubscriptionsFailedCycleWaiverCreateErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/subscriptions/{token}/failed-cycle-waiver\",\n    ...options,\n    headers: {\n      \"Content-Type\": \"application/json\",\n      ...options.headers,\n    },\n  });\n\n/**\n * Skip next billing cycle\n *\n * Skips the next billing cycle for a subscription without pausing it.\n */\nexport const subscriptionsSkip = <ThrowOnError extends boolean = true>(\n  options: Options<SubscriptionsSkipData, ThrowOnError>,\n): RequestResult<\n  SubscriptionsSkipResponses,\n  SubscriptionsSkipErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.post<\n    SubscriptionsSkipResponses,\n    SubscriptionsSkipErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/subscriptions/{token}/skip_next_billing\",\n    ...options,\n  });\n\n/**\n * Cancel a subscription\n *\n * Cancels an active subscription.\n */\nexport const subscriptionsCancel = <ThrowOnError extends boolean = true>(\n  options: Options<SubscriptionsCancelData, ThrowOnError>,\n): RequestResult<\n  SubscriptionsCancelResponses,\n  SubscriptionsCancelErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.post<\n    SubscriptionsCancelResponses,\n    SubscriptionsCancelErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/subscriptions/{token}/cancel\",\n    ...options,\n  });\n\n/**\n * Reactivate a subscription\n *\n * Reactivates a previously cancelled subscription. Returns 422 when the current plan's maximum successful billing-cycle limit has been reached.\n */\nexport const subscriptionsReactivate = <ThrowOnError extends boolean = true>(\n  options: Options<SubscriptionsReactivateData, ThrowOnError>,\n): RequestResult<\n  SubscriptionsReactivateResponses,\n  SubscriptionsReactivateErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.post<\n    SubscriptionsReactivateResponses,\n    SubscriptionsReactivateErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/subscriptions/{token}/reactivate\",\n    ...options,\n    headers: {\n      \"Content-Type\": \"application/json\",\n      ...options.headers,\n    },\n  });\n\n/**\n * Create a subscription bundle\n *\n * Bundles two or more existing subscriptions onto a shared bill date, address, and volume rep. All subscriptions must belong to the authenticated customer. Bundles are not persisted entities — the endpoint aligns each subscription's billing attributes so that they share a runtime grouping key.\n */\nexport const subscriptionBundlesCreate = <ThrowOnError extends boolean = true>(\n  options: Options<SubscriptionBundlesCreateData, ThrowOnError>,\n): RequestResult<\n  SubscriptionBundlesCreateResponses,\n  SubscriptionBundlesCreateErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.post<\n    SubscriptionBundlesCreateResponses,\n    SubscriptionBundlesCreateErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/subscription_bundles/bundle\",\n    ...options,\n    headers: {\n      \"Content-Type\": \"application/json\",\n      ...options.headers,\n    },\n  });\n\n/**\n * Retry billing on a past-due subscription\n *\n * Queues an immediate retry on a past-due subscription against whatever payment method is currently on file. The customer may retry the saved method directly unless the processor recorded a cardholder instruction to stop recurring charges; that credential must be replaced first.\n *\n *\n * The endpoint returns 200 for found subscriptions in normal operation, regardless of status — it is intentionally idempotent so the client can call it unconditionally without first checking status. A 422 is returned when the current plan's payment method is stopped for recurring charges, the maximum successful billing-cycle limit is reached or invalid, or if the server cannot persist the retry state. Use the response's `queued` field to distinguish the two outcomes:\n *\n * - `queued: true`  — the subscription was past_due, its billing date had arrived, and a retry is pending. A rapid duplicate preserves the first `next_retry_at` and does not enqueue another attempt.\n * - `queued: false` — no state change occurred, either because the subscription was not past_due or because its billing date has not yet arrived in the subscription's timezone (for example after a skip or a rescheduled next_bill_date). Treat as a no-op.\n */\nexport const subscriptionsRetry = <ThrowOnError extends boolean = true>(\n  options: Options<SubscriptionsRetryData, ThrowOnError>,\n): RequestResult<\n  SubscriptionsRetryResponses,\n  SubscriptionsRetryErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.post<\n    SubscriptionsRetryResponses,\n    SubscriptionsRetryErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/subscriptions/{token}/retry\",\n    ...options,\n  });\n\n/**\n * List todos\n *\n * Returns a paginated list of tasks scoped to the authenticated member. Filter by completion state via the `state` query parameter; defaults to `incomplete` for backwards compatibility. Incomplete tasks are ordered by due date ascending (nulls last); completed tasks by completion time descending.\n */\nexport const todosList = <ThrowOnError extends boolean = true>(\n  options: Options<TodosListData, ThrowOnError>,\n): RequestResult<TodosListResponses, TodosListErrors, ThrowOnError, \"data\"> =>\n  options.client.get<TodosListResponses, TodosListErrors, ThrowOnError, \"data\">(\n    {\n      responseStyle: \"data\",\n      url: \"/api/todos\",\n      ...options,\n    },\n  );\n\n/**\n * Create a todo\n *\n * Creates a todo owned by the authenticated member. `contact_id` is optional — omit it (or send null) to create a standalone todo not attached to a contact, matching mobile widget parity. When `contact_id` is supplied the caller must own the contact.\n */\nexport const todosCreate = <ThrowOnError extends boolean = true>(\n  options: Options<TodosCreateData, ThrowOnError>,\n): RequestResult<\n  TodosCreateResponses,\n  TodosCreateErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.post<\n    TodosCreateResponses,\n    TodosCreateErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/todos\",\n    ...options,\n    headers: {\n      \"Content-Type\": \"application/json\",\n      ...options.headers,\n    },\n  });\n\n/**\n * Delete a todo\n *\n * Deletes the given todo. Only the owning member can delete. Deleting a todo not visible to the acting member returns 404 (do not leak existence). Soft vs hard delete follows the Task model's existing destroy semantics.\n */\nexport const todosDestroy = <ThrowOnError extends boolean = true>(\n  options: Options<TodosDestroyData, ThrowOnError>,\n): RequestResult<\n  TodosDestroyResponses,\n  TodosDestroyErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.delete<\n    TodosDestroyResponses,\n    TodosDestroyErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/todos/{id}\",\n    ...options,\n  });\n\n/**\n * Update a todo\n *\n * Updates the given todo. Any non-empty subset of `body`, `due_at`, `completed`, and `contact_id` is accepted. Sending `completed: true` stamps `completed_at` with the current time; `false` clears it. A non-null `contact_id` must identify a contact owned by the authenticated user in the portal tenant company; `null` clears it. The existing widget call sending only `{ completed }` continues to work unchanged.\n */\nexport const todosUpdate = <ThrowOnError extends boolean = true>(\n  options: Options<TodosUpdateData, ThrowOnError>,\n): RequestResult<\n  TodosUpdateResponses,\n  TodosUpdateErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.patch<\n    TodosUpdateResponses,\n    TodosUpdateErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/todos/{id}\",\n    ...options,\n    headers: {\n      \"Content-Type\": \"application/json\",\n      ...options.headers,\n    },\n  });\n\n/**\n * Claim a cart\n *\n * Assigns the logged-in member as buyer_rep on an unclaimed FairShare cart. Any portal member (rep or customer) can claim. Returns an error if the cart has already been claimed.\n */\nexport const cartsClaim = <ThrowOnError extends boolean = true>(\n  options: Options<CartsClaimData, ThrowOnError>,\n): RequestResult<CartsClaimResponses, CartsClaimErrors, ThrowOnError, \"data\"> =>\n  options.client.post<\n    CartsClaimResponses,\n    CartsClaimErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/carts/{token}/claim\",\n    ...options,\n  });\n\n/**\n * Top products by direct visits\n *\n * Ranked list of the company's products by total visits to the product page (aggregates metrics_product_visits across all visit sources).\n */\nexport const productByVisits = <ThrowOnError extends boolean = true>(\n  options: Options<ProductByVisitsData, ThrowOnError>,\n): RequestResult<\n  ProductByVisitsResponses,\n  ProductByVisitsErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    ProductByVisitsResponses,\n    ProductByVisitsErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/products/by-visits\",\n    ...options,\n  });\n\n/**\n * Top products by share-link visits\n *\n * Ranked list of the company's products by click-throughs on rep share links (aggregates metrics_share_shareable_visits where shareable_type='Product').\n */\nexport const productByShares = <ThrowOnError extends boolean = true>(\n  options: Options<ProductBySharesData, ThrowOnError>,\n): RequestResult<\n  ProductBySharesResponses,\n  ProductBySharesErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    ProductBySharesResponses,\n    ProductBySharesErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/products/by-shares\",\n    ...options,\n  });\n\n/**\n * Top enrollment packs by direct visits\n *\n * Ranked list of the company's enrollment packs by total visits to the pack page (aggregates metrics_enrollment_pack_visits across all visit sources).\n */\nexport const enrollmentPackByVisits = <ThrowOnError extends boolean = true>(\n  options: Options<EnrollmentPackByVisitsData, ThrowOnError>,\n): RequestResult<\n  EnrollmentPackByVisitsResponses,\n  EnrollmentPackByVisitsErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    EnrollmentPackByVisitsResponses,\n    EnrollmentPackByVisitsErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/enrollment_packs/by-visits\",\n    ...options,\n  });\n\n/**\n * Top enrollment packs by share-link visits\n *\n * Ranked list of the company's enrollment packs by click-throughs on rep share links (aggregates metrics_share_shareable_visits where shareable_type='EnrollmentPack').\n */\nexport const enrollmentPackByShares = <ThrowOnError extends boolean = true>(\n  options: Options<EnrollmentPackBySharesData, ThrowOnError>,\n): RequestResult<\n  EnrollmentPackBySharesResponses,\n  EnrollmentPackBySharesErrors,\n  ThrowOnError,\n  \"data\"\n> =>\n  options.client.get<\n    EnrollmentPackBySharesResponses,\n    EnrollmentPackBySharesErrors,\n    ThrowOnError,\n    \"data\"\n  >({\n    responseStyle: \"data\",\n    url: \"/api/enrollment_packs/by-shares\",\n    ...options,\n  });\n","import { createContext, useContext } from \"react\";\n\nimport type { PortalTenantContentHeyApiClient } from \"@fluid-app/portal-tenant-content-api-client/client\";\n\nconst PortalTenantContentClientContext =\n  createContext<PortalTenantContentHeyApiClient | null>(null);\n\nexport const PortalTenantContentClientProvider =\n  PortalTenantContentClientContext.Provider;\n\nexport function usePortalTenantContentClient(): PortalTenantContentHeyApiClient {\n  const client = useContext(PortalTenantContentClientContext);\n  if (!client) {\n    throw new Error(\"PortalTenantContentClientProvider is missing\");\n  }\n  return client;\n}\n","import { createContext, type Provider, use } from \"react\";\nimport type { FetchClient } from \"@fluid-app/api-client-core\";\nimport type { PortalTenantHeyApiClient } from \"@fluid-app/portal-tenant-api-client/client\";\n\nconst PortalTenantClientContext =\n  createContext<PortalTenantHeyApiClient | null>(null);\nconst LegacyPortalTenantClientContext = createContext<FetchClient | null>(null);\n\nexport const PortalTenantClientProvider: Provider<PortalTenantHeyApiClient | null> =\n  PortalTenantClientContext.Provider;\nexport const LegacyPortalTenantClientProvider: Provider<FetchClient | null> =\n  LegacyPortalTenantClientContext.Provider;\n\n/**\n * Returns the portal-tenant PortalTenantHeyApiClient from context.\n * Must be used within a PortalTenantClientProvider.\n */\nexport function usePortalTenantClient(): PortalTenantHeyApiClient {\n  const client = use(PortalTenantClientContext);\n  if (!client) {\n    throw new Error(\n      \"usePortalTenantClient must be used within a PortalTenantClientProvider\",\n    );\n  }\n  return client;\n}\n\n/** Returns the shared legacy client used only by tenant packages not migrated yet. */\nexport function useLegacyPortalTenantClient(): FetchClient {\n  const client = use(LegacyPortalTenantClientContext);\n  if (!client) {\n    throw new Error(\n      \"useLegacyPortalTenantClient must be used within a LegacyPortalTenantClientProvider\",\n    );\n  }\n  return client;\n}\n","import { createContext, use } from \"react\";\nimport type { FetchClient } from \"@fluid-app/api-client-core\";\n\ninterface ShareablesCoreConfig {\n  /**\n   * Legacy FetchClient for direct API calls (e.g. products-api-client).\n   * Optional — portal-tenant contexts use BFF adapters instead.\n   */\n  client?: FetchClient;\n  user: { id: number } | null;\n  /** When true, use rep-scoped API endpoints (e.g. /users/v2025-06/media) */\n  repContext?: boolean;\n}\n\nconst ShareablesCoreContext = createContext<ShareablesCoreConfig | null>(null);\n\nexport function ShareablesCoreProvider({\n  config,\n  children,\n}: {\n  config: ShareablesCoreConfig;\n  children: React.ReactNode;\n}): React.JSX.Element {\n  return (\n    <ShareablesCoreContext.Provider value={config}>\n      {children}\n    </ShareablesCoreContext.Provider>\n  );\n}\n\nexport function useShareablesClient(): FetchClient | null {\n  const ctx = use(ShareablesCoreContext);\n  if (!ctx) {\n    throw new Error(\n      \"useShareablesClient must be used within a ShareablesCoreProvider\",\n    );\n  }\n  return ctx.client ?? null;\n}\n\nexport function useShareablesUser(): { id: number } | null {\n  const ctx = use(ShareablesCoreContext);\n  if (!ctx) {\n    throw new Error(\n      \"useShareablesUser must be used within a ShareablesCoreProvider\",\n    );\n  }\n  return ctx.user;\n}\n\nexport function useRepContext(): boolean {\n  const ctx = use(ShareablesCoreContext);\n  return ctx?.repContext ?? false;\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { useShareablesApi } from \"../shareables-api-context\";\nimport { shareablesKeys } from \"../query-keys\";\nimport type { ContentDomainApi } from \"../content-domain-api\";\nimport type { shareables } from \"../types\";\n\ninterface ProductMediaCountsResult {\n  [productId: number]: number;\n}\n\nexport type ProductMediaByProductId = Record<number, shareables.ProductMedia[]>;\n\nfunction getUniqueSortedProductIds(productIds: number[]) {\n  return [...new Set(productIds)].toSorted((a, b) => a - b);\n}\n\nasync function fetchProductMediaByProductIds(\n  api: ContentDomainApi,\n  productIds: number[],\n): Promise<ProductMediaByProductId> {\n  const productMediaByProductId: ProductMediaByProductId = {};\n\n  const promises = productIds.map(async (productId) => {\n    try {\n      const response = await api.productMedia.getProductMedia(productId);\n      productMediaByProductId[productId] = response.media || [];\n    } catch (error) {\n      console.warn(`Failed to fetch media for product ${productId}:`, error);\n      productMediaByProductId[productId] = [];\n    }\n  });\n\n  await Promise.allSettled(promises);\n  return productMediaByProductId;\n}\n\nexport function useProductMediaByProductIds(productIds: number[]) {\n  const api = useShareablesApi();\n  const normalizedProductIds = getUniqueSortedProductIds(productIds);\n\n  return useQuery({\n    queryKey: shareablesKeys.productMedia.byProductIds(normalizedProductIds),\n    queryFn: () => fetchProductMediaByProductIds(api, normalizedProductIds),\n    enabled: normalizedProductIds.length > 0,\n    staleTime: 5 * 60 * 1000,\n    gcTime: 10 * 60 * 1000,\n  });\n}\n\nexport function useProductMediaCounts(productIds: number[]) {\n  const api = useShareablesApi();\n  const normalizedProductIds = getUniqueSortedProductIds(productIds);\n\n  return useQuery({\n    queryKey: shareablesKeys.productMedia.byProductIds(normalizedProductIds),\n    queryFn: () => fetchProductMediaByProductIds(api, normalizedProductIds),\n    select: selectProductMediaCounts,\n    enabled: normalizedProductIds.length > 0,\n    staleTime: 5 * 60 * 1000,\n    gcTime: 10 * 60 * 1000,\n  });\n}\n\nfunction selectProductMediaCounts(\n  productMediaByProductId: ProductMediaByProductId,\n): ProductMediaCountsResult {\n  return Object.fromEntries(\n    Object.entries(productMediaByProductId).map(([productId, media]) => [\n      Number(productId),\n      media.length,\n    ]),\n  );\n}\n\nexport function useProductMediaCount(productId: number) {\n  const api = useShareablesApi();\n\n  return useQuery({\n    queryKey: shareablesKeys.productMedia.count(productId),\n    queryFn: async (): Promise<number> => {\n      try {\n        const response = await api.productMedia.getProductMedia(productId);\n        const mediaArray = response.media || [];\n        return mediaArray.length;\n      } catch (error) {\n        console.warn(\n          `Failed to fetch media count for product ${productId}:`,\n          error,\n        );\n        return 0;\n      }\n    },\n    enabled: !!productId,\n    staleTime: 5 * 60 * 1000,\n    gcTime: 10 * 60 * 1000,\n  });\n}\n","import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport type { shareables } from \"../types\";\nimport { useShareablesApi } from \"../shareables-api-context\";\nimport { useRepContext } from \"../context\";\nimport { shareablesKeys } from \"../query-keys\";\n\nexport interface UseMediaMutationsOptions {\n  onDeleteSuccess?: (id: number) => void;\n  onDeleteError?: (error: Error, id: number) => void;\n  onDuplicateSuccess?: (newMedia: shareables.MediumResponse) => void;\n  onDuplicateError?: (error: Error) => void;\n}\n\nexport const useMediaMutations = (options?: UseMediaMutationsOptions) => {\n  const api = useShareablesApi();\n  const queryClient = useQueryClient();\n  const repContext = useRepContext();\n\n  // Delete media mutation with optimistic updates\n  const deleteMutation = useMutation({\n    mutationFn: (id: number) => {\n      return api.media.deleteMedia(id);\n    },\n    onMutate: async (id: number) => {\n      await queryClient.cancelQueries({\n        queryKey: shareablesKeys.media.all,\n      });\n\n      // Optimistically remove from media lists\n      const previousData = queryClient.getQueriesData({\n        queryKey: shareablesKeys.media.all,\n      });\n\n      queryClient.setQueriesData<unknown>(\n        { queryKey: shareablesKeys.media.all },\n        (oldData: unknown) => {\n          if (!oldData) return oldData;\n\n          // Handle different response formats\n          if (Array.isArray(oldData)) {\n            return oldData.filter((item: { id: number }) => item.id !== id);\n          }\n\n          const dataObj = oldData as Record<string, unknown>;\n          if (dataObj.data && Array.isArray(dataObj.data)) {\n            return {\n              ...dataObj,\n              data: dataObj.data.filter(\n                (item: { id: number }) => item.id !== id,\n              ),\n            };\n          }\n\n          if (dataObj.media && Array.isArray(dataObj.media)) {\n            return {\n              ...dataObj,\n              media: dataObj.media.filter(\n                (item: { id: number }) => item.id !== id,\n              ),\n            };\n          }\n\n          return oldData;\n        },\n      );\n\n      // Remove individual media query — use the id-only prefix so every\n      // (repContext, locale) variant of this media's detail cache is\n      // cleared, not just the default-locale slot.\n      queryClient.removeQueries({\n        queryKey: shareablesKeys.media.detailById(id),\n      });\n\n      return { previousData, id };\n    },\n    onSuccess: async (_, id) => {\n      // Invalidate all media queries to refetch fresh data\n      queryClient.invalidateQueries({\n        queryKey: shareablesKeys.media.all,\n      });\n      options?.onDeleteSuccess?.(id);\n    },\n    onError: (error: Error, _id: number, context) => {\n      // Rollback optimistic updates\n      if (context?.previousData) {\n        context.previousData.forEach(([queryKey, data]) => {\n          queryClient.setQueryData(queryKey, data);\n        });\n      }\n\n      console.error(\"Error deleting media:\", error);\n      options?.onDeleteError?.(error, _id);\n    },\n  });\n\n  // Duplicate media mutation with optimistic update\n  const duplicateMutation = useMutation({\n    mutationFn: (mediaData: shareables.MediumUpdate) => {\n      return api.media.createMedia(mediaData);\n    },\n    onMutate: async (mediaData) => {\n      await queryClient.cancelQueries({\n        queryKey: shareablesKeys.media.all,\n      });\n\n      // Generate temporary ID for optimistic update\n      const tempId = Date.now();\n\n      // Create optimistic media object\n      const optimisticMedia = {\n        id: tempId,\n        title: mediaData.title || \"Untitled Media\",\n        description: mediaData.description || null,\n        media_type: \"share\",\n        media_format: null,\n        image_url: mediaData.image_url || null,\n        video_url: mediaData.video_url || null,\n        pdf_url: mediaData.pdf_url || null,\n        stripped: mediaData.description || null,\n        active: mediaData.active ?? true,\n        visibility: mediaData.visibility || null,\n        share_link: null,\n        views: 0,\n        leads: 0,\n        watch: null,\n        video_status: null,\n        duration: null,\n        cta_url: mediaData.cta_url || null,\n        cta_button_text: mediaData.cta_button_text || null,\n        cta_enabled: mediaData.cta_enabled ?? false,\n        cta_action_type: mediaData.cta_action_type || null,\n        video_shopping_enabled: mediaData.video_shopping_enabled ?? false,\n        prompts_enabled: mediaData.prompts_enabled ?? false,\n        ranks: [],\n        preview_link: null,\n        attached_shareables: [],\n        subtitles: {},\n        user_id: null,\n        created_at: new Date().toISOString(),\n      };\n\n      // Snapshot previous data for rollback\n      const previousMediaLists = queryClient.getQueriesData({\n        queryKey: shareablesKeys.media.all,\n      });\n\n      // Optimistically add media to list queries\n      queryClient.setQueriesData<unknown>(\n        { queryKey: shareablesKeys.media.all },\n        (oldData: unknown) => {\n          if (!oldData) return [optimisticMedia];\n\n          // Handle different response formats\n          if (Array.isArray(oldData)) {\n            return [optimisticMedia, ...oldData];\n          }\n\n          const dataObj = oldData as Record<string, unknown>;\n          if (dataObj.data && Array.isArray(dataObj.data)) {\n            return { ...dataObj, data: [optimisticMedia, ...dataObj.data] };\n          }\n\n          if (dataObj.media && Array.isArray(dataObj.media)) {\n            return { ...dataObj, media: [optimisticMedia, ...dataObj.media] };\n          }\n\n          return oldData;\n        },\n      );\n\n      // Set optimistic individual media query\n      queryClient.setQueryData(\n        shareablesKeys.media.detail(tempId, repContext),\n        {\n          media: optimisticMedia,\n        },\n      );\n\n      return { previousMediaLists, tempId };\n    },\n    onError: (_error, _mediaData, context) => {\n      // Rollback optimistic updates\n      if (context) {\n        context.previousMediaLists.forEach(([queryKey, data]) => {\n          queryClient.setQueryData(queryKey, data);\n        });\n\n        queryClient.removeQueries({\n          queryKey: shareablesKeys.media.detailById(context.tempId),\n        });\n      }\n\n      console.error(\"Error duplicating media:\", _error);\n      options?.onDuplicateError?.(_error);\n    },\n    onSuccess: async (data, _mediaData, context) => {\n      const realMediaId = data.id;\n\n      if (context) {\n        // Remove optimistic data\n        queryClient.removeQueries({\n          queryKey: shareablesKeys.media.detailById(context.tempId),\n        });\n      }\n\n      // Set real media data\n      queryClient.setQueryData(\n        shareablesKeys.media.detail(realMediaId, repContext),\n        {\n          media: data,\n        },\n      );\n\n      options?.onDuplicateSuccess?.(data);\n\n      // Invalidate lists to get fresh data\n      queryClient.invalidateQueries({\n        queryKey: shareablesKeys.media.all,\n        predicate: (query) => {\n          return query.queryKey.length === 1 && query.queryKey[0] === \"media\";\n        },\n      });\n    },\n  });\n\n  // Handler functions\n  const handleDelete = async (id: number) => {\n    try {\n      await deleteMutation.mutateAsync(id);\n    } catch (error) {\n      console.error(\"Delete failed:\", error);\n    }\n  };\n\n  const handleDuplicate = async (mediaData: shareables.MediumUpdate) => {\n    try {\n      await duplicateMutation.mutateAsync(mediaData);\n    } catch (error) {\n      console.error(\"Duplicate failed:\", error);\n    }\n  };\n\n  return {\n    deleteMutation,\n    duplicateMutation,\n    handleDelete,\n    handleDuplicate,\n  };\n};\n\n// ---------------------------------------------------------------------------\n// useCreateMediaMutation — dedicated create (no optimistic duplication logic)\n// ---------------------------------------------------------------------------\n\nexport interface UseCreateMediaOptions {\n  onSuccess?: (newMedia: shareables.MediumResponse) => void;\n  onError?: (error: Error) => void;\n}\n\nexport const useCreateMediaMutation = (options?: UseCreateMediaOptions) => {\n  const api = useShareablesApi();\n  const queryClient = useQueryClient();\n\n  return useMutation({\n    mutationFn: (payload: shareables.MediumUpdate) => {\n      return api.media.createMedia(payload);\n    },\n    onSuccess: (data) => {\n      queryClient.invalidateQueries({\n        queryKey: shareablesKeys.media.all,\n      });\n      options?.onSuccess?.(data);\n    },\n    onError: (error) => {\n      console.error(\"Error creating media:\", error);\n      options?.onError?.(error as Error);\n    },\n  });\n};\n","/**\n * Check if an error is a cancellation/abort error from TanStack Query or AbortController.\n */\nexport function isCancellationError(error: unknown): boolean {\n  return (\n    !!error &&\n    typeof error === \"object\" &&\n    \"name\" in error &&\n    (error.name === \"CancelledError\" || error.name === \"AbortError\")\n  );\n}\n","import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport type { shareables } from \"../types\";\nimport { useShareablesApi } from \"../shareables-api-context\";\nimport { shareablesKeys } from \"../query-keys\";\nimport { isCancellationError } from \"../utils\";\n\n// ---------------------------------------------------------------------------\n// Types for optimistic updates (internal)\n// ---------------------------------------------------------------------------\n\ninterface PlaylistItemLike {\n  id?: number | null;\n  order?: number;\n  relateable_type?: string | null;\n  relateable?: unknown;\n}\n\ntype PlaylistDetailCacheEntry = readonly [readonly unknown[], unknown];\n\nfunction updatePlaylistDetailItems(\n  old: unknown,\n  updateItems: (items: PlaylistItemLike[]) => PlaylistItemLike[],\n): unknown {\n  if (!old || typeof old !== \"object\" || !(\"playlist\" in old)) return old;\n\n  const playlistData = old as {\n    playlist: { items?: PlaylistItemLike[] };\n  };\n  return {\n    ...playlistData,\n    playlist: {\n      ...playlistData.playlist,\n      items: updateItems(playlistData.playlist.items ?? []),\n    },\n  };\n}\n\nfunction rollbackPlaylistDetailEntries(\n  queryClient: ReturnType<typeof useQueryClient>,\n  previousData: PlaylistDetailCacheEntry[] | undefined,\n): void {\n  for (const [queryKey, data] of previousData ?? []) {\n    queryClient.setQueryData(queryKey, data);\n  }\n}\n\n// ---------------------------------------------------------------------------\n// useAddItemToPlaylistMutation\n// ---------------------------------------------------------------------------\n\nexport interface UseAddItemOptions {\n  onSuccess?: (playlistId: number) => void;\n  onError?: (error: Error, playlistId: number) => void;\n}\n\ninterface AddItemToPlaylistParams {\n  playlistId: number;\n  newItem: PlaylistItemLike;\n  data: { relateable_type: string; relateable_id: number; order: number };\n}\n\nexport const useAddItemToPlaylistMutation = (options?: UseAddItemOptions) => {\n  const api = useShareablesApi();\n  const queryClient = useQueryClient();\n\n  return useMutation({\n    mutationFn: ({ playlistId, data }: AddItemToPlaylistParams) => {\n      return api.playlists.addItemToPlaylist(playlistId, {\n        items: [data],\n      });\n    },\n    onMutate: async ({ playlistId, newItem }: AddItemToPlaylistParams) => {\n      const detailPrefix = shareablesKeys.playlists.detailById(playlistId);\n      await queryClient.cancelQueries({ queryKey: detailPrefix });\n\n      const previousData = queryClient.getQueriesData({\n        queryKey: detailPrefix,\n      });\n\n      queryClient.setQueriesData({ queryKey: detailPrefix }, (old: unknown) =>\n        updatePlaylistDetailItems(old, (items) => [...items, newItem]),\n      );\n\n      return { previousData };\n    },\n    onSuccess: (_, { playlistId }) => {\n      queryClient.invalidateQueries({\n        queryKey: shareablesKeys.playlists.detailById(playlistId),\n      });\n      queryClient.invalidateQueries({\n        queryKey: shareablesKeys.playlists.all,\n      });\n      options?.onSuccess?.(playlistId);\n    },\n    onError: (error, { playlistId }, context) => {\n      // Always rollback optimistic updates first\n      rollbackPlaylistDetailEntries(queryClient, context?.previousData);\n\n      if (isCancellationError(error)) return;\n\n      console.error(\"Error adding item to playlist:\", error);\n      options?.onError?.(error as Error, playlistId);\n    },\n  });\n};\n\n// ---------------------------------------------------------------------------\n// useRemoveItemsFromPlaylistMutation\n// ---------------------------------------------------------------------------\n\nexport interface UseRemoveItemsOptions {\n  onSuccess?: (playlistId: number) => void;\n  onError?: (error: Error, playlistId: number) => void;\n}\n\ninterface RemoveItemsFromPlaylistParams {\n  playlistId: number;\n  itemIds: number[];\n}\n\nexport const useRemoveItemsFromPlaylistMutation = (\n  options?: UseRemoveItemsOptions,\n) => {\n  const api = useShareablesApi();\n  const queryClient = useQueryClient();\n\n  return useMutation({\n    mutationFn: ({ playlistId, itemIds }: RemoveItemsFromPlaylistParams) => {\n      return api.playlists.removeItemsFromPlaylist(playlistId, {\n        item_ids: itemIds,\n      });\n    },\n    onMutate: async ({\n      playlistId,\n      itemIds,\n    }: RemoveItemsFromPlaylistParams) => {\n      const detailPrefix = shareablesKeys.playlists.detailById(playlistId);\n      await queryClient.cancelQueries({ queryKey: detailPrefix });\n\n      const previousData = queryClient.getQueriesData({\n        queryKey: detailPrefix,\n      });\n\n      queryClient.setQueriesData({ queryKey: detailPrefix }, (old: unknown) =>\n        updatePlaylistDetailItems(old, (items) =>\n          items.filter((item) => item.id != null && !itemIds.includes(item.id)),\n        ),\n      );\n\n      return { previousData };\n    },\n    onSuccess: (_, { playlistId }) => {\n      queryClient.invalidateQueries({\n        queryKey: shareablesKeys.playlists.detailById(playlistId),\n      });\n      queryClient.invalidateQueries({\n        queryKey: shareablesKeys.playlists.all,\n      });\n      options?.onSuccess?.(playlistId);\n    },\n    onError: (error, { playlistId }, context) => {\n      // Always rollback optimistic updates first\n      rollbackPlaylistDetailEntries(queryClient, context?.previousData);\n\n      if (isCancellationError(error)) return;\n\n      // \"No valid playlist items found\" means the last item was removed — treat as success\n      const errorMessage =\n        error && typeof error === \"object\" && \"message\" in error\n          ? String(error.message)\n          : \"\";\n\n      if (errorMessage.includes(\"No valid playlist items found\")) {\n        queryClient.invalidateQueries({\n          queryKey: shareablesKeys.playlists.detailById(playlistId),\n        });\n        options?.onSuccess?.(playlistId);\n        return;\n      }\n\n      console.error(\"Error removing item from playlist:\", error);\n      options?.onError?.(error as Error, playlistId);\n    },\n  });\n};\n\n// ---------------------------------------------------------------------------\n// useCreatePlaylistMutation\n// ---------------------------------------------------------------------------\n\nexport interface UseCreatePlaylistOptions {\n  onSuccess?: (response: shareables.GetPlaylistResponse) => void;\n  onError?: (error: Error) => void;\n}\n\nexport const useCreatePlaylistMutation = (\n  options?: UseCreatePlaylistOptions,\n) => {\n  const api = useShareablesApi();\n  const queryClient = useQueryClient();\n\n  return useMutation({\n    mutationFn: (input: shareables.CreatePlaylistInput) => {\n      return api.playlists.createPlaylist(input);\n    },\n    onSuccess: (createdPlaylist) => {\n      queryClient.invalidateQueries({\n        queryKey: shareablesKeys.playlists.all,\n      });\n      options?.onSuccess?.(createdPlaylist);\n    },\n    onError: (error) => {\n      if (isCancellationError(error)) return;\n\n      console.error(\"Error creating playlist:\", error);\n      options?.onError?.(error as Error);\n    },\n  });\n};\n\n// ---------------------------------------------------------------------------\n// useUpdatePlaylistMutation\n// ---------------------------------------------------------------------------\n\nexport interface UseUpdatePlaylistOptions {\n  onSuccess?: (playlistId: number) => void;\n  onError?: (error: Error) => void;\n}\n\ninterface UpdatePlaylistParams {\n  playlistId: number;\n  data: shareables.UpdatePlaylistInput;\n}\n\nexport const useUpdatePlaylistMutation = (\n  options?: UseUpdatePlaylistOptions,\n) => {\n  const api = useShareablesApi();\n  const queryClient = useQueryClient();\n\n  return useMutation({\n    mutationFn: ({ playlistId, data }: UpdatePlaylistParams) => {\n      return api.playlists.updatePlaylist(playlistId, data);\n    },\n    onSuccess: (_, { playlistId }) => {\n      queryClient.invalidateQueries({\n        queryKey: shareablesKeys.playlists.all,\n      });\n      queryClient.invalidateQueries({\n        queryKey: shareablesKeys.playlists.detail(playlistId),\n      });\n      options?.onSuccess?.(playlistId);\n    },\n    onError: (error) => {\n      if (isCancellationError(error)) return;\n\n      console.error(\"Error updating playlist:\", error);\n      options?.onError?.(error as Error);\n    },\n  });\n};\n\n// ---------------------------------------------------------------------------\n// useReorderPlaylistItemsMutation\n// ---------------------------------------------------------------------------\n\nexport interface UseReorderPlaylistItemsOptions {\n  onSuccess?: (playlistId: number) => void;\n  onError?: (error: Error, playlistId: number) => void;\n}\n\ninterface ReorderPlaylistItemsParams {\n  playlistId: number;\n  data: shareables.ReorderPlaylistItemsInput;\n}\n\nexport const useReorderPlaylistItemsMutation = (\n  options?: UseReorderPlaylistItemsOptions,\n) => {\n  const api = useShareablesApi();\n  const queryClient = useQueryClient();\n\n  return useMutation({\n    mutationFn: ({ playlistId, data }: ReorderPlaylistItemsParams) => {\n      if (!api.playlists.reorderPlaylistItems) {\n        return Promise.resolve();\n      }\n      return api.playlists.reorderPlaylistItems(playlistId, data);\n    },\n    onSuccess: (_, { playlistId }) => {\n      if (api.playlists.reorderPlaylistItems) {\n        queryClient.invalidateQueries({\n          queryKey: shareablesKeys.playlists.detail(playlistId),\n        });\n      }\n      options?.onSuccess?.(playlistId);\n    },\n    onError: (error, { playlistId }) => {\n      if (isCancellationError(error)) return;\n\n      console.error(\"Error reordering playlist items:\", error);\n      options?.onError?.(error as Error, playlistId);\n    },\n  });\n};\n","import { createContext, useContext, type Provider } from \"react\";\nimport type { FilePickerApi } from \"./schemas/file-picker-api\";\n\nconst FilePickerApiContext = createContext<FilePickerApi | null>(null);\n\nexport const FilePickerApiProvider: Provider<FilePickerApi | null> =\n  FilePickerApiContext.Provider;\n\nexport function useFilePickerApi(): FilePickerApi {\n  const api = useContext(FilePickerApiContext);\n  if (!api) {\n    throw new Error(\n      \"useFilePickerApi must be used within a FilePickerApiProvider\",\n    );\n  }\n  return api;\n}\n","import { z } from \"zod\";\n\ntype DamVariantApi = {\n  id: string;\n  url: string | null;\n  file_name: string;\n  mime_type: string;\n  content: any;\n  created_at: string;\n  updated_at: string;\n  default: boolean;\n  is_original: boolean;\n  is_text: boolean;\n  media_type: string;\n  processing_status: string;\n  tags: string[];\n};\n\nexport const damVariantSchema: z.ZodType<DamVariantApi> = z.object({\n  id: z.string(),\n  url: z.string().nullable(),\n  file_name: z.string(),\n  mime_type: z.string(),\n  content: z.any().nullable(),\n  created_at: z.string(),\n  updated_at: z.string(),\n  default: z.boolean(),\n  is_original: z.boolean(),\n  is_text: z.boolean(),\n  media_type: z.string(),\n  processing_status: z.string(),\n  tags: z.array(z.string()),\n});\n\ntype DamAssetApi = {\n  id: number;\n  canonical_path: string;\n  category: string;\n  code: string;\n  company: string;\n  created_at: string;\n  default_variant_id: string;\n  default_variant_url?: string;\n  description: string;\n  name: string;\n  updated_at: string;\n  variants?: DamVariantApi[];\n};\n\nexport const damAssetSchema: z.ZodType<DamAssetApi> = z.object({\n  id: z.number(),\n  canonical_path: z.string(),\n  category: z.string(),\n  code: z.string(),\n  company: z.string(),\n  created_at: z.string(),\n  default_variant_id: z.string(),\n  default_variant_url: z.string().optional(),\n  description: z.string(),\n  name: z.string(),\n  updated_at: z.string(),\n  variants: z.array(damVariantSchema).optional(),\n});\n\ntype DamTreeFolderNode = {\n  asset_code?: string | Record<string, unknown>;\n  name?: string | Record<string, unknown>;\n  category?: string | Record<string, unknown>;\n  variants?: unknown[] | Record<string, unknown>;\n  [key: string]: unknown;\n};\n\nexport const damTreeFolderNodeSchema: z.ZodType<DamTreeFolderNode> = z\n  .object({\n    asset_code: z\n      .union([z.string(), z.record(z.string(), z.unknown())])\n      .optional(),\n    name: z.union([z.string(), z.record(z.string(), z.unknown())]).optional(),\n    category: z\n      .union([z.string(), z.record(z.string(), z.unknown())])\n      .optional(),\n    variants: z\n      .union([z.array(z.unknown()), z.record(z.string(), z.unknown())])\n      .optional(),\n  })\n  .passthrough();\n\nexport const damTreeSchema: z.ZodType<Record<string, any>> = z.record(\n  z.string(),\n  z.union([\n    z.lazy(() => damTreeSchema),\n    damAssetSchema,\n    damTreeFolderNodeSchema,\n  ]),\n);\n\ntype DamQueryResponse = {\n  path: string;\n  tree: Record<string, any>;\n  meta?: { next_cursor?: string; total_count?: number };\n};\n\nexport const damQueryResponseSchema: z.ZodType<DamQueryResponse> = z.object({\n  path: z.string(),\n  tree: damTreeSchema,\n  meta: z\n    .object({\n      next_cursor: z.string().optional(),\n      total_count: z.number().optional(),\n    })\n    .optional(),\n});\n\ntype DamAssetCreateRequest = {\n  asset: {\n    file: any;\n    name: string;\n    description?: string;\n    tags?: string;\n  };\n};\n\nexport const damAssetCreateRequestSchema: z.ZodType<DamAssetCreateRequest> =\n  z.object({\n    asset: z.object({\n      file: z.any(),\n      name: z.string(),\n      description: z.string().optional(),\n      tags: z.string().optional(),\n    }),\n  });\n\ntype DamAssetCreateResponse = {\n  asset: DamAssetApi;\n  meta: { request_id: string; timestamp: string };\n};\n\nexport const damAssetCreateResponseSchema: z.ZodType<DamAssetCreateResponse> =\n  z.object({\n    asset: damAssetSchema,\n    meta: z.object({\n      request_id: z.string(),\n      timestamp: z.string(),\n    }),\n  });\n\n// Schema for creating asset with placeholder (for ImageKit direct upload)\ntype DamAssetCreateWithPlaceholderRequest = {\n  placeholder_asset: {\n    mime_type: string;\n    name?: string;\n    description?: string;\n  };\n  skip_autotagging?: boolean;\n};\n\nexport const damAssetCreateWithPlaceholderRequestSchema: z.ZodType<DamAssetCreateWithPlaceholderRequest> =\n  z.object({\n    placeholder_asset: z.object({\n      mime_type: z.string(),\n      name: z.string().optional(),\n      description: z.string().optional(),\n    }),\n    skip_autotagging: z.boolean().optional(),\n  });\n\n// Schema for creating asset path without file upload (legacy)\ntype DamAssetPathCreateRequest = {\n  asset?: {\n    file: any;\n    name: string;\n    description?: string;\n    tags?: string;\n  };\n  text_asset?: {\n    file_name: string;\n    mime_type: string;\n    text: string;\n    name?: string;\n    description?: string;\n    tags?: string;\n  };\n  placeholder_asset?: {\n    mime_type: string;\n    name?: string;\n    description?: string;\n  };\n  skip_autotagging?: boolean;\n};\n\nexport const damAssetPathCreateRequestSchema: z.ZodType<DamAssetPathCreateRequest> =\n  z.object({\n    asset: z\n      .object({\n        file: z.any(),\n        name: z.string(),\n        description: z.string().optional(),\n        tags: z.string().optional(),\n      })\n      .optional(),\n    text_asset: z\n      .object({\n        file_name: z.string(),\n        mime_type: z.string(),\n        text: z.string(),\n        name: z.string().optional(),\n        description: z.string().optional(),\n        tags: z.string().optional(),\n      })\n      .optional(),\n    placeholder_asset: z\n      .object({\n        mime_type: z.string(),\n        name: z.string().optional(),\n        description: z.string().optional(),\n      })\n      .optional(),\n    skip_autotagging: z.boolean().optional(),\n  });\n\ntype DamAssetPathCreateResponse = {\n  asset: { id: number; canonical_path: string; name: string };\n  meta: { request_id: string; timestamp: string };\n};\n\nexport const damAssetPathCreateResponseSchema: z.ZodType<DamAssetPathCreateResponse> =\n  z.object({\n    asset: z.object({\n      id: z.number(),\n      canonical_path: z.string(),\n      name: z.string(),\n    }),\n    meta: z.object({\n      request_id: z.string(),\n      timestamp: z.string(),\n    }),\n  });\n\nexport type { DamVariantApi, DamAssetApi };\nexport type DamTreeApi = z.infer<typeof damTreeSchema>;\nexport type { DamQueryResponse };\nexport type { DamAssetCreateRequest };\nexport type { DamAssetCreateResponse };\nexport type { DamAssetCreateWithPlaceholderRequest };\nexport type { DamAssetPathCreateRequest };\nexport type { DamAssetPathCreateResponse };\n","const EXTENSION_MIME_MAP: Record<string, string> = {\n  \".heic\": \"image/heic\",\n  \".heics\": \"image/heic-sequence\",\n  \".heif\": \"image/heif\",\n};\n\n/**\n * Resolves MIME type from file.type, falling back to extension-based lookup\n * when the browser returns an empty type (e.g. HEIC on Chrome/Firefox).\n */\nexport function getFileMimeType(file: File): string {\n  if (file.type) return file.type;\n  const ext = file.name.match(/\\.[^.]+$/)?.[0]?.toLowerCase();\n  return (ext && EXTENSION_MIME_MAP[ext]) || \"application/octet-stream\";\n}\n\n/**\n * Validates if a file type matches the accepted types\n */\nexport function isFileTypeAccepted(\n  mimeType: string,\n  fileName: string,\n  acceptTypes: string[],\n): boolean {\n  if (!acceptTypes || acceptTypes.length === 0) {\n    return true; // No restrictions\n  }\n\n  return acceptTypes.some((acceptType) => {\n    // Handle MIME type patterns (e.g., \"image/*\", \"video/*\")\n    if (acceptType.includes(\"*\")) {\n      const baseType = acceptType.split(\"/\")[0];\n      const fileBaseType = mimeType.split(\"/\")[0];\n      return baseType === fileBaseType;\n    }\n\n    // Handle exact MIME type matches (e.g., \"image/jpeg\", \"video/mp4\")\n    if (acceptType.includes(\"/\") && !acceptType.startsWith(\".\")) {\n      return mimeType === acceptType;\n    }\n\n    // Handle file extension matches (e.g., \".jpg\", \".mp4\")\n    if (acceptType.startsWith(\".\")) {\n      const lastDotIndex = fileName.lastIndexOf(\".\");\n      if (lastDotIndex === -1) return false;\n      const fileExtension = fileName.toLowerCase().substring(lastDotIndex);\n      return fileExtension === acceptType.toLowerCase();\n    }\n\n    return false;\n  });\n}\n\n/**\n * Gets a user-friendly description of accepted file types\n */\nexport function getAcceptedTypesDescription(acceptTypes: string[]): string {\n  if (!acceptTypes || acceptTypes.length === 0) {\n    return \"Any file type\";\n  }\n\n  const descriptions: string[] = [];\n  const seenTypes = new Set<string>();\n\n  acceptTypes.forEach((type) => {\n    if (seenTypes.has(type)) return;\n    seenTypes.add(type);\n\n    if (type === \"image/*\") {\n      descriptions.push(\"Images\");\n    } else if (type === \"video/*\") {\n      descriptions.push(\"Videos\");\n    } else if (type === \"audio/*\") {\n      descriptions.push(\"Audio\");\n    } else if (type === \"application/pdf\") {\n      descriptions.push(\"PDF files\");\n    } else if (type.startsWith(\".\")) {\n      descriptions.push(`${type.toUpperCase()} files`);\n    } else if (type.includes(\"/\")) {\n      descriptions.push(type);\n    }\n  });\n\n  if (descriptions.length === 0) {\n    return acceptTypes.join(\", \");\n  }\n\n  if (descriptions.length === 1) {\n    return descriptions[0]!;\n  }\n\n  if (descriptions.length === 2) {\n    return `${descriptions[0]!} and ${descriptions[1]!}`;\n  }\n\n  return `${descriptions.slice(0, -1).join(\", \")}, and ${descriptions[descriptions.length - 1]!}`;\n}\n","import type { DamAssetCreateResponse } from \"@fluid-app/file-picker-core\";\nimport type { PortalTenantContentHeyApiClient } from \"@fluid-app/portal-tenant-content-api-client/client\";\n\nexport interface DamUploadStrategy {\n  uploadFile(params: {\n    file: File;\n    name: string;\n    description?: string;\n    tags?: string[];\n    onProgress?: (progress: number) => void;\n    companyId?: number;\n  }): Promise<DamAssetCreateResponse>;\n}\n\nexport interface FilePickerClientConfig {\n  contentClient: PortalTenantContentHeyApiClient;\n  uploadStrategy?: DamUploadStrategy;\n  unsplashAccessKey?: string;\n  proxyEndpoint?: string; // defaults to \"/api/proxy-url\"\n}\n\nexport interface FilePickerClient {\n  contentClient: PortalTenantContentHeyApiClient;\n  uploadStrategy?: DamUploadStrategy;\n  unsplashAccessKey?: string;\n  proxyEndpoint: string;\n}\n\nexport function createFilePickerClient(\n  config: FilePickerClientConfig,\n): FilePickerClient {\n  return {\n    contentClient: config.contentClient,\n    uploadStrategy: config.uploadStrategy,\n    unsplashAccessKey: config.unsplashAccessKey,\n    proxyEndpoint: config.proxyEndpoint ?? \"/api/proxy-url\",\n  };\n}\n","import {\n  damAssetSchema,\n  getFileMimeType,\n  type CreateDamAssetParams,\n  type CreateDamAssetPathForAssetsParams,\n  type DamAssetCreateResponse,\n  type DamAssetCreateWithPlaceholderRequest,\n  type DamAssetPathCreateRequest,\n  type DamAssetPathCreateResponse,\n} from \"@fluid-app/file-picker-core\";\nimport type { PortalTenantContentHeyApiClient } from \"@fluid-app/portal-tenant-content-api-client/client\";\nimport {\n  damAssetPathsCreate,\n  damAssetsCreate,\n} from \"@fluid-app/portal-tenant-content-api-client/sdk\";\nimport type {\n  DamAssetPathsCreateResponse,\n  DamAssetsCreateResponse,\n} from \"@fluid-app/portal-tenant-content-api-client/types\";\nimport type { DamUploadStrategy } from \"../client\";\n\nexport type { CreateDamAssetParams };\n\nexport interface CreateDamAssetPathParams {\n  name: string;\n  description?: string;\n  tags?: string[];\n  companyId?: number;\n  mimeType?: string;\n  textContent?: string;\n  fileName?: string;\n  skipAutotagging?: boolean;\n}\n\nfunction mapCreateResponse(\n  response: DamAssetsCreateResponse,\n): DamAssetCreateResponse {\n  const raw = response.asset ?? {};\n  return {\n    asset: damAssetSchema.parse({\n      ...raw,\n      canonical_path: raw.canonical_path ?? \"\",\n      category: raw.category ?? \"\",\n      company: raw.company ?? \"\",\n      description: raw.description ?? \"\",\n      default_variant_id: raw.default_variant_id ?? \"\",\n    }),\n    meta: {\n      request_id: response.meta?.request_id ?? \"\",\n      timestamp: response.meta?.timestamp ?? new Date().toISOString(),\n    },\n  };\n}\n\nfunction mapAssetPathCreateResponse(\n  response: DamAssetPathsCreateResponse,\n): DamAssetPathCreateResponse {\n  const assetPath = response.asset_path ?? {};\n  return {\n    asset: {\n      id: assetPath.id ?? 0,\n      canonical_path: assetPath.path ?? \"\",\n      name: assetPath.asset_code ?? \"\",\n    },\n    meta: {\n      request_id: response.meta?.request_id ?? \"\",\n      timestamp: response.meta?.timestamp ?? new Date().toISOString(),\n    },\n  };\n}\n\nfunction mapPlaceholderResponse(\n  response: DamAssetsCreateResponse,\n): DamAssetPathCreateResponse {\n  return {\n    asset: {\n      id: response.asset?.id ?? 0,\n      canonical_path: response.asset?.canonical_path ?? \"\",\n      name: response.asset?.name ?? \"\",\n    },\n    meta: {\n      request_id: response.meta?.request_id ?? \"\",\n      timestamp: response.meta?.timestamp ?? new Date().toISOString(),\n    },\n  };\n}\n\n/**\n * Create a DAM asset. Text files use FormData upload; non-text files\n * delegate to the provided uploadStrategy (e.g. ImageKit).\n * If no uploadStrategy is provided, all files use FormData upload.\n */\nexport async function createDamAsset(\n  client: PortalTenantContentHeyApiClient,\n  params: CreateDamAssetParams,\n  uploadStrategy?: DamUploadStrategy,\n): Promise<DamAssetCreateResponse> {\n  const mimeType = getFileMimeType(params.file);\n  const isTextFile =\n    mimeType.startsWith(\"text/\") ||\n    mimeType === \"application/json\" ||\n    mimeType === \"application/xml\" ||\n    params.file.name.endsWith(\".txt\") ||\n    params.file.name.endsWith(\".json\") ||\n    params.file.name.endsWith(\".xml\") ||\n    params.file.name.endsWith(\".csv\");\n\n  // For text files, use traditional FormData upload\n  if (isTextFile) {\n    return createDamAssetViaFormData(client, params);\n  }\n\n  // For non-text files, use upload strategy if available\n  if (uploadStrategy) {\n    return uploadStrategy.uploadFile(params);\n  }\n\n  // Fallback to FormData upload\n  return createDamAssetViaFormData(client, params);\n}\n\nasync function createDamAssetViaFormData(\n  client: PortalTenantContentHeyApiClient,\n  params: CreateDamAssetParams,\n): Promise<DamAssetCreateResponse> {\n  const formData = new FormData();\n  formData.append(\"asset[file]\", params.file);\n  formData.append(\"asset[name]\", params.name);\n\n  if (params.description) {\n    formData.append(\"asset[description]\", params.description);\n  }\n\n  if (params.tags && params.tags.length > 0) {\n    formData.append(\"asset[tags]\", params.tags.join(\",\"));\n  }\n\n  const response = await damAssetsCreate({\n    client,\n    body: {\n      asset: {\n        name: params.name,\n        ...(params.description ? { description: params.description } : {}),\n      },\n    },\n    bodySerializer: () => formData,\n    headers: { \"Content-Type\": null },\n  });\n  return mapCreateResponse(response);\n}\n\n/**\n * Create DAM asset with placeholder for direct upload strategies\n */\nexport async function createDamAssetWithPlaceholder(\n  client: PortalTenantContentHeyApiClient,\n  params: CreateDamAssetPathParams,\n): Promise<DamAssetPathCreateResponse> {\n  if (!params.mimeType) {\n    throw new Error(\"mimeType is required for createDamAssetWithPlaceholder\");\n  }\n  const requestData: DamAssetCreateWithPlaceholderRequest = {\n    placeholder_asset: {\n      mime_type: params.mimeType,\n      name: params.name,\n      description: params.description,\n    },\n  };\n\n  if (params.skipAutotagging !== undefined) {\n    requestData.skip_autotagging = params.skipAutotagging;\n  }\n\n  const response = await damAssetsCreate({\n    client,\n    body: { asset: { name: params.name, description: params.description } },\n    bodySerializer: () => JSON.stringify(requestData),\n  });\n  return mapPlaceholderResponse(response);\n}\n\n/**\n * Create DAM asset path without file upload (legacy)\n */\nexport async function createDamAssetPath(\n  client: PortalTenantContentHeyApiClient,\n  params: CreateDamAssetPathParams,\n): Promise<DamAssetPathCreateResponse> {\n  const requestData: DamAssetPathCreateRequest = {};\n\n  if (params.textContent && params.mimeType && params.fileName) {\n    requestData.text_asset = {\n      file_name: params.fileName,\n      mime_type: params.mimeType,\n      text: params.textContent,\n      name: params.name,\n      description: params.description,\n      tags: params.tags?.join(\",\"),\n    };\n  } else if (params.mimeType) {\n    requestData.placeholder_asset = {\n      mime_type: params.mimeType,\n      name: params.name,\n      description: params.description,\n    };\n  } else {\n    requestData.asset = {\n      file: null,\n      name: params.name,\n      description: params.description,\n      tags: params.tags?.join(\",\"),\n    };\n  }\n\n  if (params.skipAutotagging !== undefined) {\n    requestData.skip_autotagging = params.skipAutotagging;\n  }\n\n  const response = await damAssetsCreate({\n    client,\n    body: { asset: { name: params.name, description: params.description } },\n    bodySerializer: () => JSON.stringify(requestData),\n  });\n  return mapPlaceholderResponse(response);\n}\n\nexport type { CreateDamAssetPathForAssetsParams } from \"@fluid-app/file-picker-core\";\n\nexport async function createDamAssetPathForAssets(\n  client: PortalTenantContentHeyApiClient,\n  { asset_paths, code }: CreateDamAssetPathForAssetsParams,\n): Promise<DamAssetPathCreateResponse> {\n  const response = await damAssetPathsCreate({\n    client,\n    path: { asset_code: code },\n    body: { asset_path: { path: asset_paths.join(\",\") } },\n  });\n  return mapAssetPathCreateResponse(response);\n}\n","import {\n  damQueryResponseSchema,\n  type DamQueryParams,\n  type DamQueryResponse,\n} from \"@fluid-app/file-picker-core\";\nimport type { PortalTenantContentHeyApiClient } from \"@fluid-app/portal-tenant-content-api-client/client\";\nimport {\n  damAssetsDestroy,\n  damAssetsDiscard,\n  damQuery,\n} from \"@fluid-app/portal-tenant-content-api-client/sdk\";\nimport type { DamQueryData } from \"@fluid-app/portal-tenant-content-api-client/types\";\n\nexport async function queryDamAssets(\n  client: PortalTenantContentHeyApiClient,\n  params: DamQueryParams,\n): Promise<DamQueryResponse> {\n  const response = await damQuery({\n    client,\n    body: params satisfies DamQueryData[\"body\"],\n  });\n  return damQueryResponseSchema.parse({\n    ...response,\n    meta: response.meta\n      ? { next_cursor: response.meta.pagination?.next_cursor ?? undefined }\n      : undefined,\n  });\n}\n\nexport async function deleteDamAsset(\n  client: PortalTenantContentHeyApiClient,\n  code: string,\n): Promise<unknown> {\n  return damAssetsDestroy({ client, path: { code } });\n}\n\nexport async function discardDamAsset(\n  client: PortalTenantContentHeyApiClient,\n  code: string,\n): Promise<unknown> {\n  return damAssetsDiscard({ client, path: { code } });\n}\n","import { z } from \"zod\";\nimport type {\n  UnsplashImage,\n  UnsplashSearchResponse,\n} from \"@fluid-app/file-picker-core\";\n\nexport type { UnsplashImage, UnsplashSearchResponse };\n\nconst unsplashImageSchema: z.ZodType<UnsplashImage> = z.object({\n  id: z.string(),\n  urls: z.object({\n    raw: z.string(),\n    full: z.string(),\n    regular: z.string(),\n    small: z.string(),\n    thumb: z.string(),\n  }),\n  alt_description: z.string().nullable(),\n  description: z.string().nullable(),\n  user: z.object({ name: z.string(), username: z.string() }),\n  width: z.number(),\n  height: z.number(),\n});\n\nconst unsplashSearchResponseSchema: z.ZodType<UnsplashSearchResponse> =\n  z.object({\n    results: z.array(unsplashImageSchema),\n    total: z.number(),\n    total_pages: z.number(),\n  });\n\n/**\n * Search Unsplash for photos matching a query.\n */\nexport async function searchUnsplash(\n  query: string,\n  accessKey: string,\n  page: number = 1,\n  perPage: number = 20,\n): Promise<UnsplashSearchResponse> {\n  const response = await fetch(\n    `https://api.unsplash.com/search/photos?query=${encodeURIComponent(query)}&page=${page}&per_page=${perPage}&client_id=${accessKey}`,\n  );\n\n  if (!response.ok) {\n    throw new Error(\"Failed to search Unsplash\");\n  }\n\n  return unsplashSearchResponseSchema.parse(await response.json());\n}\n","import { z } from \"zod\";\nimport type { UrlProxyResponse } from \"@fluid-app/file-picker-core\";\n\nexport type { UrlProxyResponse };\n\nconst urlProxyResponseSchema: z.ZodType<UrlProxyResponse> = z.object({\n  data: z.string(),\n  contentType: z.string(),\n  size: z.number(),\n});\n\n/**\n * Proxy a URL fetch through the backend to bypass CORS restrictions.\n * The backend fetches the file and returns it as base64-encoded data.\n *\n * @param url - The URL to fetch\n * @param proxyEndpoint - The proxy endpoint (defaults to \"/api/proxy-url\")\n */\nexport async function proxyUrlFetch(\n  url: string,\n  proxyEndpoint: string = \"/api/proxy-url\",\n): Promise<UrlProxyResponse> {\n  const response = await fetch(proxyEndpoint, {\n    method: \"POST\",\n    headers: {\n      \"Content-Type\": \"application/json\",\n    },\n    body: JSON.stringify({ url }),\n  });\n\n  if (!response.ok) {\n    const errorData = await response.json().catch(() => ({\n      error: \"Failed to proxy URL fetch\",\n    }));\n    throw new Error(\n      (errorData as { error?: string }).error || `HTTP ${response.status}`,\n    );\n  }\n\n  const data: unknown = await response.json();\n  return urlProxyResponseSchema.parse(data);\n}\n","import type { FilePickerApi } from \"@fluid-app/file-picker-core\";\nimport type { FilePickerClient } from \"./client\";\nimport { createDamAsset, createDamAssetPathForAssets } from \"./api/dam-assets\";\nimport {\n  queryDamAssets,\n  deleteDamAsset,\n  discardDamAsset,\n} from \"./api/dam-query\";\nimport { searchUnsplash } from \"./api/unsplash\";\nimport { proxyUrlFetch } from \"./api/url-proxy\";\n\n/**\n * Creates a FilePickerApi-compatible adapter backed by the real API client\n * functions. The returned object satisfies the FilePickerApi interface\n * from @fluid-app/file-picker-core via structural typing.\n */\nexport function createFilePickerApi(client: FilePickerClient): FilePickerApi {\n  return {\n    createDamAsset: (params: Parameters<typeof createDamAsset>[1]) =>\n      createDamAsset(client.contentClient, params, client.uploadStrategy),\n    queryDamAssets: (params: Parameters<typeof queryDamAssets>[1]) =>\n      queryDamAssets(client.contentClient, params),\n    searchUnsplash: (query: string, page?: number, perPage?: number) => {\n      if (!client.unsplashAccessKey) {\n        throw new Error(\"Unsplash access key not configured\");\n      }\n      return searchUnsplash(query, client.unsplashAccessKey, page, perPage);\n    },\n    deleteDamAsset: (code: string) =>\n      deleteDamAsset(client.contentClient, code),\n    discardDamAsset: (code: string) =>\n      discardDamAsset(client.contentClient, code),\n    createDamAssetPathForAssets: (\n      params: Parameters<typeof createDamAssetPathForAssets>[1],\n    ) => createDamAssetPathForAssets(client.contentClient, params),\n    proxyUrlFetch: (url: string) => proxyUrlFetch(url, client.proxyEndpoint),\n  };\n}\n","import {\n  createFilePickerApi,\n  createFilePickerClient,\n} from \"@fluid-app/file-picker-api-client\";\nimport type { FilePickerApi } from \"@fluid-app/file-picker-core\";\nimport type { PortalTenantContentHeyApiClient } from \"@fluid-app/portal-tenant-content-api-client/client\";\n\n/**\n * Adapts the portal tenant content client to the file-picker port.\n *\n * The file-picker API package owns the transport mapping for the generated DAM\n * operations. This adapter only wires the configured portal client into that\n * package, preserving the domain port boundary.\n */\nexport function createFilePickerApiAdapter(\n  contentClient: PortalTenantContentHeyApiClient,\n): FilePickerApi {\n  return createFilePickerApi(createFilePickerClient({ contentClient }));\n}\n","/**\n * Port interface for toggling content favorites for the authenticated member.\n *\n * This is intentionally narrower than the generated API: callers cannot pass\n * arbitrary Rails model names through the port.\n */\n\nexport const CONTENT_FAVORITE_TYPES = [\n  \"Product\",\n  \"Medium\",\n  \"Promotion\",\n  \"Page\",\n  \"Playlist\",\n  \"EnrollmentPack\",\n  \"Category\",\n  \"Collection\",\n  \"Post\",\n] as const;\n\nexport type ContentFavoriteType = (typeof CONTENT_FAVORITE_TYPES)[number];\n\nexport interface ContentFavorite {\n  favoriteable_id: number;\n  favoriteable_type: ContentFavoriteType;\n  is_favorited: boolean;\n}\n\nexport interface ContentFavoriteToggleInput {\n  favoriteable_id: number;\n  favoriteable_type: ContentFavoriteType;\n}\n\nexport interface ContentFavoritesApi {\n  toggleFavorite(input: ContentFavoriteToggleInput): Promise<ContentFavorite>;\n}\n","/**\n * Portal Content Domain Adapter — Implements ContentDomainApi using the\n * portal-tenant Content BFF endpoints.\n *\n * `createPortalContentDomainApiAdapter` provides the composite domain adapter.\n * Focused public factories support capability and screen wiring that consumes\n * only one content sub-API.\n */\n\nimport type { PortalTenantContentHeyApiClient } from \"@fluid-app/portal-tenant-content-api-client/client\";\nimport type { PortalTenantHeyApiClient } from \"@fluid-app/portal-tenant-api-client/client\";\nimport type {\n  ContentMediaApi,\n  ContentMediaProductsApi,\n  media,\n} from \"@fluid-app/shareables-core/media-api\";\nimport type {\n  ContentPlaylistsApi,\n  playlists,\n} from \"@fluid-app/shareables-core/playlists-api\";\nimport type {\n  ContentSharesApi,\n  shares,\n} from \"@fluid-app/shareables-core/shares-api\";\nimport type {\n  ContentDamAssetsApi,\n  damAssets,\n} from \"@fluid-app/shareables-core/dam-assets-api\";\nimport {\n  CONTENT_FAVORITE_TYPES,\n  type ContentFavorite,\n  type ContentFavoritesApi,\n  type ContentFavoriteType,\n} from \"@fluid-app/shareables-core/favorites-api\";\nimport type {\n  ContentMetricsApi,\n  metrics,\n} from \"@fluid-app/shareables-core/metrics-api\";\nimport type {\n  ContentPagesApi,\n  pages,\n} from \"@fluid-app/shareables-core/pages-api\";\nimport type {\n  ContentEnrollmentPacksApi,\n  enrollmentPacks,\n} from \"@fluid-app/shareables-core/enrollment-packs-api\";\nimport type {\n  MediaApi,\n  PlaylistsApi,\n  FileResourcesApi,\n  ProductMediaApi,\n  ShareApi,\n} from \"@fluid-app/shareables-core/shareables-api\";\nimport type { ContentDomainApi } from \"@fluid-app/shareables-core/content-domain-api\";\nimport type {\n  shareables,\n  PlaylistsQuery,\n} from \"@fluid-app/shareables-core/types\";\nimport { portalTenantContentTransport as portalTenantContent } from \"./portal-tenant-content-transport\";\nimport * as portalTenant from \"@fluid-app/portal-tenant-api-client/sdk\";\n\n// ============================================================================\n// Media — Raw BFF adapter (private)\n// ============================================================================\n\nfunction mapMedia(\n  raw: NonNullable<\n    Awaited<ReturnType<typeof portalTenantContent.media_show>>[\"media\"]\n  >,\n): media.Media {\n  return {\n    id: raw.id ?? 0,\n    title: raw.title ?? \"\",\n    description: raw.description ?? null,\n    content_format: raw.content_format ?? null,\n    status: raw.status ?? \"active\",\n    url: raw.url ?? null,\n    thumbnail_url: raw.thumbnail_url ?? null,\n    owner_type: raw.owner_type ?? \"\",\n    cta: raw.cta\n      ? {\n          enabled: raw.cta.enabled ?? null,\n          type: raw.cta.type ?? null,\n          button_text: raw.cta.button_text ?? null,\n          button_color: raw.cta.button_color ?? null,\n          button_description: raw.cta.button_description ?? null,\n          action_url: raw.cta.action_url ?? null,\n        }\n      : null,\n    seo: raw.seo\n      ? {\n          title: raw.seo.title ?? null,\n          description: raw.seo.description ?? null,\n          image_url: raw.seo.image_url ?? null,\n          block_crawler: raw.seo.block_crawler ?? null,\n        }\n      : null,\n    created_at: raw.created_at ?? \"\",\n    updated_at: raw.updated_at ?? \"\",\n  };\n}\n\nfunction mapMediaMeta(\n  raw: Awaited<ReturnType<typeof portalTenantContent.media_list>>[\"meta\"],\n): media.MediaListResponse[\"meta\"] {\n  return {\n    request_id: raw?.request_id ?? null,\n    timestamp: raw?.timestamp ?? \"\",\n    pagination: raw?.pagination\n      ? {\n          cursor: raw.pagination.cursor ?? null,\n          limit: raw.pagination.limit,\n          next_cursor: raw.pagination.next_cursor ?? null,\n          prev_cursor: raw.pagination.prev_cursor ?? null,\n        }\n      : undefined,\n  };\n}\n\nfunction createRawMediaAdapter(\n  client: PortalTenantContentHeyApiClient,\n): ContentMediaApi {\n  return {\n    listMedia: async (params) => {\n      const response = await portalTenantContent.media_list(client, {\n        \"page[cursor]\": params?.cursor,\n        \"page[limit]\": params?.limit,\n        \"filter[title]\": params?.[\"filter[title]\"],\n        \"filter[ownership]\": params?.[\"filter[ownership]\"],\n        \"filter[content_format]\": params?.[\"filter[content_format]\"],\n        sort: params?.sort,\n        language_iso: params?.language_iso,\n      });\n      return {\n        media: (response.media ?? []).map(mapMedia),\n        meta: mapMediaMeta(response.meta),\n      };\n    },\n\n    createMedia: async (body) => {\n      const response = await portalTenantContent.media_create(client, {\n        media: body,\n      });\n      if (!response.media) {\n        throw new Error(\"Media create response missing media\");\n      }\n      return {\n        media: mapMedia(response.media),\n        meta: mapMediaMeta(response.meta),\n      };\n    },\n\n    getMedia: async (id, language_iso) => {\n      const response = await portalTenantContent.media_show(\n        client,\n        id,\n        language_iso ? { language_iso } : undefined,\n      );\n      if (!response.media) {\n        throw new Error(\"Media show response missing media\");\n      }\n      return {\n        media: mapMedia(response.media),\n        meta: mapMediaMeta(response.meta),\n      };\n    },\n\n    updateMedia: async (id, body, language_iso) => {\n      const response = await portalTenantContent.media_update(\n        client,\n        id,\n        { media: body },\n        language_iso ? { language_iso } : undefined,\n      );\n      if (!response.media) {\n        throw new Error(\"Media update response missing media\");\n      }\n      return {\n        media: mapMedia(response.media),\n        meta: mapMediaMeta(response.meta),\n      };\n    },\n\n    deleteMedia: async (id) => {\n      const response = await portalTenantContent.media_destroy(client, id);\n      return {\n        media: { id: response.media?.id ?? 0 },\n        meta: mapMediaMeta(response.meta),\n      };\n    },\n  };\n}\n\n/**\n * Creates a ContentMediaProductsApi adapter backed by the portal-tenant content BFF.\n */\nexport function createPortalTenantMediaProductsAdapter(\n  client: PortalTenantContentHeyApiClient,\n): ContentMediaProductsApi {\n  return {\n    listMediaProducts: async (mediumId, params) => {\n      const response = await portalTenantContent.media_products_list(\n        client,\n        mediumId,\n        {\n          \"page[cursor]\": params?.cursor,\n          \"page[limit]\": params?.limit,\n          language_iso: params?.language_iso,\n        },\n      );\n      return {\n        media_products: (response.media_products ?? []).map((p) => ({\n          id: p.id ?? 0,\n          name: p.name ?? undefined,\n          slug: p.slug ?? null,\n          image_url: p.image_url ?? null,\n          price: p.price ?? null,\n          currency: p.currency ?? null,\n          added_at: p.added_at ?? null,\n        })),\n        meta: mapMediaMeta(response.meta),\n      };\n    },\n\n    addMediaProduct: async (mediumId, body) => {\n      const response = await portalTenantContent.media_products_add(\n        client,\n        mediumId,\n        { product: { id: body.id } },\n      );\n      const p = response.media_product ?? {};\n      return {\n        media_product: {\n          id: p.id ?? 0,\n          name: p.name ?? undefined,\n          slug: p.slug ?? null,\n          image_url: p.image_url ?? null,\n          price: p.price ?? null,\n          currency: p.currency ?? null,\n          added_at: p.added_at ?? null,\n        },\n        meta: {\n          request_id: response.meta?.request_id ?? null,\n          timestamp: response.meta?.timestamp ?? \"\",\n        },\n      };\n    },\n\n    removeMediaProduct: async (mediumId, productId) => {\n      const response = await portalTenantContent.media_products_remove(\n        client,\n        mediumId,\n        productId,\n      );\n      return {\n        media_product: {\n          product_id: response.media_product?.product_id ?? 0,\n        },\n        meta: {\n          request_id: response.meta?.request_id ?? null,\n          timestamp: response.meta?.timestamp ?? \"\",\n        },\n      };\n    },\n  };\n}\n\n// ============================================================================\n// Media — ShareablesApi-compatible adapter (private)\n// ============================================================================\n\nfunction mediaKindFromType(mediaType: string): string | null {\n  if (mediaType === \"video\") return \"video\";\n  if (mediaType === \"image\") return \"image\";\n  if (mediaType === \"document\" || mediaType === \"pdf\") return \"pdf\";\n  return null;\n}\n\nfunction toBffMediumResponse(bff: media.Media): shareables.MediumResponse {\n  const kind = bff.content_format ?? null;\n  const isVideo = kind === \"video\";\n  const isPdf = kind === \"pdf\";\n  const ctaData = bff.cta;\n  const seoData = bff.seo;\n\n  return {\n    id: bff.id,\n    user_id: null,\n    owner_type: bff.owner_type ?? null,\n    media_type: bff.content_format ?? \"image\",\n    media_format: bff.content_format ?? \"image\",\n    image_url:\n      !isVideo && !isPdf\n        ? (bff.url ?? bff.thumbnail_url ?? null)\n        : (bff.thumbnail_url ?? null),\n    video_url: isVideo ? (bff.url ?? null) : null,\n    pdf_url: isPdf ? (bff.url ?? null) : null,\n    title: bff.title,\n    description: {\n      id: null,\n      name: null,\n      body: bff.description ?? null,\n      record_type: null,\n      record_id: null,\n      created_at: bff.created_at ?? null,\n      updated_at: bff.updated_at ?? null,\n      locale: null,\n    },\n    stripped: bff.description ?? null,\n    kind,\n    active: bff.status === \"active\",\n    visibility: null,\n    share_link: null,\n    views: 0,\n    leads: 0,\n    watch: null,\n    video_status: null,\n    duration: null,\n    cta_url: ctaData?.action_url ?? null,\n    cta_button_text: ctaData?.button_text ?? null,\n    cta_enabled: ctaData?.enabled ?? false,\n    cta_action_type: ctaData?.type ?? null,\n    video_shopping_enabled: false,\n    prompts_enabled: false,\n    ranks: [],\n    preview_link: null,\n    attached_shareables: [],\n    created_at: bff.created_at,\n    settings: {\n      cta: ctaData\n        ? {\n            enabled: ctaData.enabled ?? undefined,\n            type: ctaData.type ?? undefined,\n            url: ctaData.action_url ?? undefined,\n            button_text: ctaData.button_text ?? undefined,\n            button_color: ctaData.button_color ?? undefined,\n            button_description: ctaData.button_description ?? undefined,\n          }\n        : null,\n      seo: seoData\n        ? {\n            title: seoData.title ?? undefined,\n            description: seoData.description ?? undefined,\n            image_url: seoData.image_url ?? undefined,\n            block_crawler: seoData.block_crawler ?? undefined,\n          }\n        : null,\n    },\n  };\n}\n\nfunction createMediaAdapter(client: PortalTenantContentHeyApiClient): MediaApi {\n  const portAdapter = createRawMediaAdapter(client);\n  const cursorByPage = new Map<number, string>();\n  let lastFilterKey = \"\";\n\n  return {\n    list: async (options) => {\n      const response = await portAdapter.listMedia({\n        cursor: options?.[\"page[cursor]\"],\n        limit: options?.[\"page[limit]\"],\n        \"filter[title]\": options?.[\"filter[title]\"],\n        \"filter[ownership]\": options?.[\"filter[ownership]\"],\n        \"filter[content_format]\": options?.[\"filter[content_format]\"],\n        sort: options?.sort,\n        language_iso: options?.language_iso,\n      });\n      return {\n        media: response.media.map(toBffMediumResponse),\n        nextCursor: response.meta.pagination?.next_cursor ?? null,\n      };\n    },\n\n    getMedia: async (options) => {\n      const pageNumber = options?.page ?? 1;\n\n      // Clear cursor cache when search/sort/ownership/locale filters change\n      const filterKey = `${options?.search_query ?? \"\"}|${options?.sorted_by ?? \"\"}|${options?.ownership ?? \"\"}|${options?.language_iso ?? \"\"}`;\n      if (filterKey !== lastFilterKey) {\n        cursorByPage.clear();\n        lastFilterKey = filterKey;\n      }\n\n      const cursor = pageNumber > 1 ? cursorByPage.get(pageNumber) : undefined;\n\n      // Map UI sort values (\"title_asc\", \"title_desc\") to BFF sort.\n      const rawSort = options?.sorted_by;\n      let bffSort: \"title_asc\" | \"title_desc\" | undefined;\n      if (rawSort === \"title_asc\") {\n        bffSort = \"title_asc\";\n      } else if (rawSort === \"title_desc\") {\n        bffSort = \"title_desc\";\n      }\n\n      const ownership = options?.ownership;\n      const bffOwnership: \"all\" | \"mine\" | \"company\" | undefined =\n        ownership === \"all\" || ownership === \"mine\" || ownership === \"company\"\n          ? ownership\n          : undefined;\n\n      const response = await portAdapter.listMedia({\n        cursor,\n        limit: options?.per_page,\n        \"filter[title]\": options?.search_query,\n        \"filter[ownership]\": bffOwnership,\n        sort: bffSort,\n        language_iso: options?.language_iso,\n      });\n\n      const nextCursor = response.meta.pagination?.next_cursor;\n      if (nextCursor) {\n        cursorByPage.set(pageNumber + 1, nextCursor);\n      }\n\n      const transformedItems = response.media.map(toBffMediumResponse);\n\n      // Cursor-based pagination doesn't expose a real total. Synthesize\n      // a value so `page * PAGE_SIZE < total_count` yields the correct\n      // hasNextPage boolean: if there's a next cursor, total exceeds the\n      // current offset; otherwise it's exactly the items seen so far.\n      const perPage = options?.per_page ?? 24;\n      const syntheticTotal = nextCursor\n        ? pageNumber * perPage + 1\n        : (pageNumber - 1) * perPage + transformedItems.length;\n\n      return {\n        data: transformedItems,\n        status: \"success\",\n        media: transformedItems,\n        meta: {\n          total_count: syntheticTotal,\n          current: pageNumber,\n          per_page: perPage,\n          pages: nextCursor ? pageNumber + 1 : pageNumber,\n          next: nextCursor ? pageNumber + 1 : null,\n          previous: pageNumber > 1 ? pageNumber - 1 : null,\n        },\n      };\n    },\n\n    getMediaById: async (id, language_iso) => {\n      const response = await portAdapter.getMedia(id, language_iso);\n      const medium = toBffMediumResponse(response.media);\n      return {\n        data: medium,\n        status: \"success\",\n        media: medium,\n      };\n    },\n\n    createMedia: async (mediaData) => {\n      // Per backend contract: send `content_format` on every POST that\n      // includes a `url`, otherwise backend defaults to image_url/kind=\"image\"\n      // regardless of the actual asset. The UI derives kind from MIME type\n      // (see deriveMediaType in MediaCreateScreen).\n      const contentFormat: \"image\" | \"video\" | \"pdf\" | \"ppt\" | undefined =\n        mediaData.kind === \"image\" ||\n        mediaData.kind === \"video\" ||\n        mediaData.kind === \"pdf\" ||\n        mediaData.kind === \"ppt\"\n          ? mediaData.kind\n          : undefined;\n      const response = await portAdapter.createMedia({\n        title: mediaData.title ?? \"\",\n        description: mediaData.description,\n        media_type: mediaData.media_type ?? \"image\",\n        url:\n          mediaData.image_url ??\n          mediaData.video_url ??\n          mediaData.pdf_url ??\n          undefined,\n        content_format: contentFormat,\n      });\n      return toBffMediumResponse(response.media);\n    },\n\n    updateMedia: async (id, mediaData, language_iso) => {\n      const updateBody: media.MediaUpdateBody = {\n        title: mediaData.title,\n        description: mediaData.description,\n      };\n      // Map active boolean to status enum\n      if (mediaData.active !== undefined) {\n        updateBody.status = mediaData.active ? \"active\" : \"draft\";\n      }\n      // Map replacement media asset URL (image/video/pdf) → BFF single `url`\n      const newUrl =\n        mediaData.image_url ??\n        mediaData.video_url ??\n        mediaData.pdf_url ??\n        undefined;\n      if (newUrl !== undefined) {\n        updateBody.url = newUrl;\n      }\n      // Map UI `kind` (from FilePickerResult) → BFF `content_format`.\n      // Per backend contract: must be sent alongside `url` when asset type\n      // changes, otherwise backend falls back to medium's stored `kind` and\n      // the new URL lands in the wrong column. Runtime-narrow since the\n      // source `MediumUpdate.kind` is typed as a broader string.\n      if (\n        mediaData.kind === \"image\" ||\n        mediaData.kind === \"video\" ||\n        mediaData.kind === \"pdf\" ||\n        mediaData.kind === \"ppt\"\n      ) {\n        updateBody.content_format = mediaData.kind;\n      }\n      // Thumbnail override (for video thumbnail captures)\n      if (mediaData.thumbnail_url !== undefined) {\n        updateBody.thumbnail_url = mediaData.thumbnail_url;\n      }\n      // Map CTA from settings to top-level.\n      // Note: to disable an existing CTA, callers set { enabled: false };\n      // sending settings.cta = null is not currently supported by the BFF\n      // (MediaUpdate.cta has no null variant), so we only forward when cta\n      // is a defined object.\n      if (mediaData.settings?.cta) {\n        const rawType = mediaData.settings.cta.type;\n        // Runtime-narrow CTA type rather than casting — the source type is\n        // `string | null | undefined` so an unknown string would otherwise\n        // be forwarded unvalidated to the BFF.\n        const ctaType =\n          rawType === \"link\" ||\n          rawType === \"cart\" ||\n          rawType === \"email\" ||\n          rawType === \"phone\"\n            ? rawType\n            : undefined;\n        updateBody.cta = {\n          enabled: mediaData.settings.cta.enabled,\n          type: ctaType,\n          button_text: mediaData.settings.cta.button_text,\n          button_color: mediaData.settings.cta.button_color,\n          button_description: mediaData.settings.cta.button_description,\n          action_url: mediaData.settings.cta.url,\n        };\n      }\n      // Map SEO from settings to top-level\n      if (mediaData.settings?.seo) {\n        updateBody.seo = {\n          title: mediaData.settings.seo.title,\n          description: mediaData.settings.seo.description,\n          image_url: mediaData.settings.seo.image_url,\n          block_crawler: mediaData.settings.seo.block_crawler ?? undefined,\n        };\n      }\n      const response = await portAdapter.updateMedia(\n        id,\n        updateBody,\n        language_iso,\n      );\n      return toBffMediumResponse(response.media);\n    },\n\n    deleteMedia: async (id) => {\n      await portAdapter.deleteMedia(id);\n      return { success: true };\n    },\n  };\n}\n\n// ============================================================================\n// Playlists — Raw BFF adapter (private)\n// ============================================================================\n\nfunction mapPlaylist(\n  raw: NonNullable<\n    Awaited<ReturnType<typeof portalTenantContent.playlists_show>>[\"playlist\"]\n  >,\n): playlists.Playlist {\n  return {\n    id: raw.id ?? 0,\n    title: raw.title ?? \"\",\n    description: raw.description ?? null,\n    items_count: raw.items_count ?? 0,\n    user_id: raw.member_id ?? undefined,\n    is_favorited: raw.is_favorited,\n    image_url: raw.image_url ?? null,\n    created_at: raw.created_at ?? \"\",\n    updated_at: raw.updated_at ?? \"\",\n  };\n}\n\nfunction mapPlaylistItem(\n  raw: NonNullable<\n    Awaited<\n      ReturnType<typeof portalTenantContent.playlists_items_list>\n    >[\"playlist_items\"]\n  >[number],\n): playlists.PlaylistItem {\n  return {\n    id: raw.id,\n    content_type: raw.content_type,\n    content_id: raw.content_id,\n    position: raw.position,\n    created_at: raw.created_at,\n    content: raw.content as playlists.PlaylistItemContent,\n  };\n}\n\nfunction mapPlaylistsMeta(\n  raw: Awaited<ReturnType<typeof portalTenantContent.playlists_list>>[\"meta\"],\n): playlists.PlaylistsListResponse[\"meta\"] {\n  return {\n    request_id: raw?.request_id ?? null,\n    timestamp: raw?.timestamp ?? \"\",\n    pagination: raw?.pagination\n      ? {\n          cursor: raw.pagination.cursor ?? null,\n          limit: raw.pagination.limit,\n          next_cursor: raw.pagination.next_cursor ?? null,\n          prev_cursor: raw.pagination.prev_cursor ?? null,\n        }\n      : undefined,\n  };\n}\n\nfunction createRawPlaylistsAdapter(\n  client: PortalTenantContentHeyApiClient,\n): ContentPlaylistsApi {\n  return {\n    listPlaylists: async (params) => {\n      const response = await portalTenantContent.playlists_list(client, {\n        \"page[cursor]\": params?.cursor,\n        \"page[limit]\": params?.limit,\n        \"filter[title]\": params?.[\"filter[title]\"],\n        \"filter[ownership]\": params?.[\"filter[ownership]\"],\n        sort: params?.sort,\n      });\n      return {\n        playlists: (response.playlists ?? []).map(mapPlaylist),\n        meta: mapPlaylistsMeta(response.meta),\n      };\n    },\n\n    createPlaylist: async (body) => {\n      const response = await portalTenantContent.playlists_create(client, {\n        playlist: body,\n      });\n      return {\n        playlist: mapPlaylist(response.playlist ?? {}),\n        meta: mapPlaylistsMeta(response.meta),\n      };\n    },\n\n    getPlaylist: async (id) => {\n      const response = await portalTenantContent.playlists_show(client, id);\n      return {\n        playlist: mapPlaylist(response.playlist ?? {}),\n        meta: mapPlaylistsMeta(response.meta),\n      };\n    },\n\n    updatePlaylist: async (id, body) => {\n      const response = await portalTenantContent.playlists_update(client, id, {\n        playlist: body,\n      });\n      return {\n        playlist: mapPlaylist(response.playlist ?? {}),\n        meta: mapPlaylistsMeta(response.meta),\n      };\n    },\n\n    deletePlaylist: async (id) => {\n      const response = await portalTenantContent.playlists_destroy(client, id);\n      return {\n        playlist: { id: response.playlist?.id ?? 0 },\n        meta: mapPlaylistsMeta(response.meta),\n      };\n    },\n\n    listPlaylistItems: async (playlistId, params) => {\n      const response = await portalTenantContent.playlists_items_list(\n        client,\n        playlistId,\n        {\n          \"page[cursor]\": params?.cursor,\n          \"page[limit]\": params?.limit,\n          language_iso: params?.language_iso,\n        },\n      );\n      return {\n        playlist_items: (response.playlist_items ?? []).map(mapPlaylistItem),\n        meta: mapPlaylistsMeta(response.meta),\n      };\n    },\n\n    addPlaylistItem: async (playlistId, body) => {\n      const response = await portalTenantContent.playlists_items_add(\n        client,\n        playlistId,\n        { item: body },\n      );\n      const rawItem = response.playlist_item;\n      if (!rawItem) {\n        throw new Error(\"Playlist item add response missing playlist_item\");\n      }\n      return {\n        playlist_item: mapPlaylistItem(rawItem),\n        meta: mapPlaylistsMeta(response.meta),\n      };\n    },\n\n    removePlaylistItem: async (playlistId, itemId) => {\n      const response = await portalTenantContent.playlists_items_remove(\n        client,\n        playlistId,\n        itemId,\n      );\n      return {\n        playlist_item: { id: response.playlist_item?.id ?? 0 },\n        meta: mapPlaylistsMeta(response.meta),\n      };\n    },\n\n    reorderPlaylistItems: async (playlistId, body) => {\n      const response = await portalTenantContent.playlists_items_reorder(\n        client,\n        playlistId,\n        body,\n      );\n      return {\n        playlist_id: response.playlist_id ?? playlistId,\n        meta: mapPlaylistsMeta(response.meta),\n      };\n    },\n  };\n}\n\n// ============================================================================\n// Playlists — ShareablesApi-compatible adapter (private)\n// ============================================================================\n\n// Map BFF content_type ↔ legacy admin polymorphic relateable_type used by the\n// Playlists UI, plus reverse for outgoing add-item payloads.\nconst CONTENT_TYPE_TO_RELATEABLE: Record<\n  playlists.ContentType,\n  \"Medium\" | \"Page\" | \"Product\" | \"EnrollmentPack\"\n> = {\n  media: \"Medium\",\n  page: \"Page\",\n  product: \"Product\",\n  enrollment_pack: \"EnrollmentPack\",\n};\n\nconst RELATEABLE_TO_CONTENT_TYPE: Record<string, playlists.ContentType> = {\n  Medium: \"media\",\n  Media: \"media\",\n  media: \"media\",\n  Page: \"page\",\n  page: \"page\",\n  Product: \"product\",\n  product: \"product\",\n  EnrollmentPack: \"enrollment_pack\",\n  enrollment_pack: \"enrollment_pack\",\n};\n\nfunction firstImageUrl(\n  images: Array<{ url?: string | null }> | undefined,\n): string | null {\n  return images?.[0]?.url ?? null;\n}\n\nfunction toShareablePlaylistItem(\n  item: playlists.PlaylistItem,\n): shareables.PlaylistItem {\n  const relateableType = CONTENT_TYPE_TO_RELATEABLE[item.content_type];\n  const base: shareables.PlaylistItem = {\n    id: item.id,\n    order: item.position ?? undefined,\n    relateable_type: relateableType,\n    relateable: { id: item.content_id },\n  };\n\n  switch (item.content_type) {\n    case \"media\": {\n      const c = item.content as playlists.MediaContent;\n      const isVideo = c.content_format === \"video\";\n      const isPdf = c.content_format === \"pdf\";\n      base.title = c.title ?? \"Untitled\";\n      base.image_url =\n        isVideo || isPdf\n          ? (c.thumbnail_url ?? null)\n          : (c.url ?? c.thumbnail_url ?? null);\n      base.kind = mediaKindFromType(c.content_format ?? \"\");\n      base.video_url = isVideo ? (c.url ?? null) : null;\n      base.duration = null;\n      base.media_format = c.content_format ?? null;\n      base.relateable = {\n        id: c.id,\n        title: c.title,\n        image_url: base.image_url,\n        media_format: c.content_format ?? null,\n        video_url: base.video_url,\n        kind: base.kind,\n        description: {\n          id: null,\n          name: null,\n          body: c.description ?? null,\n          record_type: null,\n          record_id: null,\n          created_at: c.created_at ?? null,\n          updated_at: c.updated_at ?? null,\n          locale: null,\n        },\n      };\n      break;\n    }\n    case \"page\": {\n      const c = item.content as playlists.PageContent;\n      base.title = c.title ?? \"Untitled\";\n      base.image_url = c.image_url ?? null;\n      base.relateable = {\n        id: c.id,\n        title: c.title,\n        slug: c.slug ?? null,\n        image_url: c.image_url ?? null,\n        status: c.status,\n        description: {\n          id: null,\n          name: null,\n          body: c.description ?? null,\n          record_type: null,\n          record_id: null,\n          created_at: null,\n          updated_at: null,\n          locale: null,\n        },\n      };\n      break;\n    }\n    case \"product\": {\n      const c = item.content as playlists.ProductContent;\n      const image = firstImageUrl(c.images);\n      base.title = c.name;\n      base.image_url = image;\n      base.relateable = {\n        id: c.id,\n        title: c.name,\n        slug: c.slug ?? null,\n        price: c.price ?? null,\n        display_price: c.price ?? null,\n        image_url: image,\n        status: c.status ?? null,\n        description: {\n          id: null,\n          name: null,\n          body: c.description ?? null,\n          record_type: null,\n          record_id: null,\n          created_at: c.created_at ?? null,\n          updated_at: null,\n          locale: null,\n        },\n        images: (c.images ?? []).map((img) => ({\n          image_url: img.url ?? null,\n        })),\n      };\n      break;\n    }\n    case \"enrollment_pack\": {\n      const c = item.content as playlists.EnrollmentPackContent;\n      const image = firstImageUrl(c.images);\n      base.title = c.title;\n      base.image_url = image;\n      base.relateable = {\n        id: c.id,\n        title: c.title,\n        slug: c.slug ?? null,\n        canonical_url: c.url ?? null,\n        image_url: image,\n        description: {\n          id: null,\n          name: null,\n          body: c.description ?? null,\n          record_type: null,\n          record_id: null,\n          created_at: null,\n          updated_at: null,\n          locale: null,\n        },\n        images: (c.images ?? []).map((img) => ({\n          image_url: img.url ?? null,\n        })),\n      };\n      break;\n    }\n    default: {\n      // If a new ContentType literal is added without updating this switch,\n      // TypeScript will reject this assignment at compile time. At runtime,\n      // unknown discriminators surface as a typed error rather than silently\n      // producing a row with no title/image.\n      const _exhaustive: never = item.content_type;\n      throw new Error(\n        `Unhandled playlist item content_type: ${String(_exhaustive)}`,\n      );\n    }\n  }\n\n  return base;\n}\n\nfunction toBffPlaylist(\n  bff: playlists.Playlist,\n  items?: shareables.PlaylistItem[],\n): shareables.Playlist {\n  return {\n    id: bff.id,\n    title: bff.title,\n    description: bff.description ?? null,\n    image_url: bff.image_url ?? null,\n    slug: null,\n    active: true,\n    user_id: bff.user_id ?? null,\n    is_favorited: bff.is_favorited ?? false,\n    items: items ?? [],\n    items_count: bff.items_count,\n  };\n}\n\nfunction createPlaylistsAdapter(\n  client: PortalTenantContentHeyApiClient,\n): PlaylistsApi {\n  const portAdapter = createRawPlaylistsAdapter(client);\n\n  return {\n    getPlaylists: async (options?: PlaylistsQuery) => {\n      // The UI sends Rails-style sort (\"-title\", \"title\", \"-created_at\")\n      // but the BFF expects \"title_asc\", \"title_desc\", etc.\n      const rawSort = options?.sort;\n      let bffSort:\n        | \"title_asc\"\n        | \"title_desc\"\n        | \"created_at_asc\"\n        | \"created_at_desc\"\n        | undefined;\n      if (rawSort === \"title_asc\" || rawSort === \"title\") {\n        bffSort = \"title_asc\";\n      } else if (rawSort === \"title_desc\" || rawSort === \"-title\") {\n        bffSort = \"title_desc\";\n      } else if (rawSort === \"created_at_asc\" || rawSort === \"created_at\") {\n        bffSort = \"created_at_asc\";\n      } else if (rawSort === \"created_at_desc\" || rawSort === \"-created_at\") {\n        bffSort = \"created_at_desc\";\n      }\n\n      const response = await portAdapter.listPlaylists({\n        cursor: options?.[\"page[cursor]\"],\n        limit: options?.[\"page[limit]\"],\n        \"filter[title]\": options?.[\"filter[title]\"],\n        \"filter[ownership]\": options?.[\"filter[ownership]\"],\n        sort: bffSort,\n      });\n\n      return {\n        playlists: response.playlists.map((p) => toBffPlaylist(p)),\n        meta: {\n          request_id: response.meta.request_id ?? \"\",\n          timestamp: response.meta.timestamp ?? \"\",\n          pagination: {\n            cursor: response.meta.pagination?.cursor ?? null,\n            limit: response.meta.pagination?.limit ?? 12,\n            prev_cursor: response.meta.pagination?.prev_cursor ?? null,\n            next_cursor: response.meta.pagination?.next_cursor ?? null,\n            total_count: 0,\n            total_pages: 0,\n          },\n        },\n      };\n    },\n\n    getPlaylistById: async (id, language_iso) => {\n      // Fetch playlist metadata and all items in parallel.\n      // Items are cursor-paginated so we follow next_cursor until exhausted.\n      const response = await portAdapter.getPlaylist(id);\n\n      const allItems: playlists.PlaylistItem[] = [];\n      let cursor: string | undefined;\n      const MAX_PAGES = 50; // Safety limit: 50 pages × 100 items = 5,000 items max\n      for (let i = 0; i < MAX_PAGES; i++) {\n        const page = await portAdapter.listPlaylistItems(id, {\n          cursor,\n          limit: 100,\n          language_iso,\n        });\n        allItems.push(...page.playlist_items);\n        cursor = page.meta.pagination?.next_cursor ?? undefined;\n        if (!cursor) break;\n      }\n\n      const items: shareables.PlaylistItem[] = allItems.map(\n        toShareablePlaylistItem,\n      );\n\n      return {\n        playlist: toBffPlaylist(response.playlist, items),\n        meta: {\n          request_id: response.meta.request_id ?? \"\",\n          timestamp: response.meta.timestamp ?? \"\",\n        },\n      };\n    },\n\n    createPlaylist: async (data) => {\n      const response = await portAdapter.createPlaylist({\n        title: data.playlist.title,\n        description: data.playlist.description,\n      });\n      return {\n        playlist: toBffPlaylist(response.playlist),\n        meta: {\n          request_id: response.meta.request_id ?? \"\",\n          timestamp: response.meta.timestamp ?? \"\",\n        },\n      };\n    },\n\n    updatePlaylist: async (id, data) => {\n      const response = await portAdapter.updatePlaylist(id, {\n        title: data.playlist.title,\n        description: data.playlist.description,\n      });\n      return {\n        playlist: toBffPlaylist(response.playlist),\n        meta: {\n          request_id: response.meta.request_id ?? \"\",\n          timestamp: response.meta.timestamp ?? \"\",\n        },\n      };\n    },\n\n    addItemToPlaylist: async (id, data) => {\n      // Sequential dispatch — the BFF assigns playlist position by insert\n      // order when the request omits an explicit position, and shared\n      // explicit positions across concurrent requests would race. for-of\n      // ordering keeps the playlist deterministic regardless of caller.\n      for (const item of data.items) {\n        const contentType = RELATEABLE_TO_CONTENT_TYPE[item.relateable_type];\n        if (!contentType) {\n          throw new Error(\n            `Unsupported relateable_type for playlist item: \"${item.relateable_type}\"`,\n          );\n        }\n        // Only forward a real, positive position.\n        //\n        // An explicit 0 is rejected outright: the schema is\n        // `optional(:position).maybe(:integer, gt?: 0)`. An absent order was\n        // not rejected — `JSON.stringify(NaN)` is `null` and `maybe` accepts\n        // nil — but it did land the item at the front, since the BFF only\n        // appends for an absent position once fluid#20645 ships. Before that\n        // merge both shapes prepend.\n        const position =\n          typeof item.order === \"number\" && item.order > 0\n            ? item.order\n            : undefined;\n\n        await portAdapter.addPlaylistItem(id, {\n          content_type: contentType,\n          content_id: item.relateable_id,\n          ...(position === undefined ? {} : { position }),\n        });\n      }\n      return {\n        id,\n        title: \"\",\n        description: null,\n        image_url: null,\n        slug: null,\n        active: true,\n        user_id: null,\n        is_favorited: false,\n        items: [],\n        items_count: 0,\n      } satisfies shareables.Playlist;\n    },\n\n    removeItemsFromPlaylist: async (playlistId, data) => {\n      await Promise.all(\n        data.item_ids.map((itemId) =>\n          portAdapter.removePlaylistItem(playlistId, itemId),\n        ),\n      );\n      return {\n        id: playlistId,\n        title: \"\",\n        description: null,\n        image_url: null,\n        slug: null,\n        active: true,\n        user_id: null,\n        is_favorited: false,\n        items: [],\n        items_count: 0,\n      } satisfies shareables.Playlist;\n    },\n\n    reorderPlaylistItems: async (playlistId, data) => {\n      await portAdapter.reorderPlaylistItems(playlistId, {\n        items: data.items,\n      });\n    },\n  };\n}\n\n// ============================================================================\n// Shares — Raw BFF adapter (private)\n// ============================================================================\n\nfunction isShareableType(\n  value: string | undefined,\n): value is shares.ShareableType {\n  return (\n    value === \"media\" ||\n    value === \"product\" ||\n    value === \"library\" ||\n    value === \"page\"\n  );\n}\n\nfunction mapShare(\n  raw: NonNullable<\n    Awaited<ReturnType<typeof portalTenantContent.shares_list>>[\"shares\"]\n  >[number],\n): shares.Share {\n  return {\n    id: raw.id ?? 0,\n    url: raw.url ?? \"\",\n    shareable_type: isShareableType(raw.shareable_type)\n      ? raw.shareable_type\n      : \"media\",\n    shareable_id: raw.shareable_id ?? 0,\n    created_at: raw.created_at ?? \"\",\n  };\n}\n\nfunction mapSharesMeta(\n  raw: Awaited<ReturnType<typeof portalTenantContent.shares_list>>[\"meta\"],\n): shares.SharesListResponse[\"meta\"] {\n  return {\n    request_id: raw?.request_id ?? null,\n    timestamp: raw?.timestamp ?? \"\",\n    pagination: raw?.pagination\n      ? {\n          cursor: raw.pagination.cursor ?? null,\n          limit: raw.pagination.limit,\n          next_cursor: raw.pagination.next_cursor ?? null,\n          prev_cursor: raw.pagination.prev_cursor ?? null,\n        }\n      : undefined,\n  };\n}\n\nfunction createRawSharesAdapter(\n  client: PortalTenantContentHeyApiClient,\n): ContentSharesApi {\n  return {\n    listShares: async (params) => {\n      const response = await portalTenantContent.shares_list(client, {\n        \"page[cursor]\": params?.cursor,\n        \"page[limit]\": params?.limit,\n      });\n      return {\n        shares: (response.shares ?? []).map(mapShare),\n        meta: mapSharesMeta(response.meta),\n      };\n    },\n\n    createShare: async (body) => {\n      const response = await portalTenantContent.shares_create(client, {\n        share: body,\n      });\n      return {\n        share: mapShare(response.share ?? {}),\n        meta: mapSharesMeta(response.meta),\n      };\n    },\n  };\n}\n\n// ============================================================================\n// Shares — ShareablesApi-compatible adapter (private)\n// ============================================================================\n\nconst SHAREABLE_TYPE_MAP: Record<string, shares.ShareableType> = {\n  Medium: \"media\",\n  media: \"media\",\n  Product: \"product\",\n  product: \"product\",\n  Library: \"library\",\n  library: \"library\",\n  Page: \"page\",\n  page: \"page\",\n};\n\nconst SUPPORTED_SHAREABLE_LABELS = [\n  ...new Set(Object.values(SHAREABLE_TYPE_MAP)),\n].join(\", \");\n\nfunction createShareAdapter(client: PortalTenantContentHeyApiClient): ShareApi {\n  const portAdapter = createRawSharesAdapter(client);\n\n  return {\n    createShareLink: async (input) => {\n      if (!input.relateableId) {\n        throw new Error(\"Cannot create share link without a relateableId\");\n      }\n      const shareableType = SHAREABLE_TYPE_MAP[input.relateableType];\n      if (!shareableType) {\n        throw new Error(\n          `Cannot share a \"${input.relateableType}\" — shareable links support only ${SUPPORTED_SHAREABLE_LABELS}.`,\n        );\n      }\n\n      const response = await portAdapter.createShare({\n        shareable_type: shareableType,\n        shareable_id: input.relateableId,\n      });\n\n      return response.share.url;\n    },\n  };\n}\n\n// ============================================================================\n// Pages — Raw BFF adapter (private)\n// ============================================================================\n\nfunction mapPage(\n  raw: NonNullable<\n    Awaited<ReturnType<typeof portalTenantContent.pages_list>>[\"pages\"]\n  >[number],\n): pages.Page {\n  return {\n    id: raw.id ?? 0,\n    title: raw.title ?? null,\n    slug: raw.slug ?? null,\n    source: raw.source ?? null,\n    status: raw.status ?? \"unpublished\",\n    countries: (raw.countries ?? []).map((c) => ({\n      code: c.code ?? \"\",\n      name: c.name ?? \"\",\n      currency_code: c.currency_code ?? \"\",\n      states: (c.states ?? []).map((s) => ({\n        code: s.code ?? \"\",\n        name: s.name ?? \"\",\n      })),\n    })),\n    description: raw.description ?? null,\n    image_url: raw.image_url ?? null,\n  };\n}\n\nfunction mapPagesMeta(\n  raw: Awaited<ReturnType<typeof portalTenantContent.pages_list>>[\"meta\"],\n): pages.PagesListResponse[\"meta\"] {\n  return {\n    request_id: raw?.request_id ?? null,\n    timestamp: raw?.timestamp ?? \"\",\n    pagination: raw?.pagination\n      ? {\n          cursor: raw.pagination.cursor ?? null,\n          limit: raw.pagination.limit,\n          next_cursor: raw.pagination.next_cursor ?? null,\n          prev_cursor: raw.pagination.prev_cursor ?? null,\n        }\n      : undefined,\n  };\n}\n\nfunction createRawPagesAdapter(\n  client: PortalTenantContentHeyApiClient,\n): ContentPagesApi {\n  return {\n    listPages: async (params) => {\n      const response = await portalTenantContent.pages_list(client, {\n        \"page[cursor]\": params?.cursor,\n        \"page[limit]\": params?.limit,\n        \"filter[title]\": params?.[\"filter[title]\"],\n        sort: params?.sort,\n        language_iso: params?.language_iso,\n      });\n      return {\n        pages: (response.pages ?? []).map(mapPage),\n        meta: mapPagesMeta(response.meta),\n      };\n    },\n\n    getPage: async (id, language_iso) => {\n      const response = await portalTenantContent.pages_show(\n        client,\n        id,\n        language_iso ? { language_iso } : undefined,\n      );\n      if (!response.page) {\n        throw new Error(`Page ${id} not found`);\n      }\n      return {\n        page: mapPage(response.page),\n        share_link: response.share_link ?? null,\n        meta: mapPagesMeta(response.meta),\n      };\n    },\n  };\n}\n\n// ============================================================================\n// Enrollment Packs — Raw BFF adapter (private)\n//\n// The list endpoint lives on portal-tenant (not portal-tenant-content).\n// The port (`ContentEnrollmentPacksApi`) is namespace-agnostic — this is\n// the only adapter file that has to know.\n// ============================================================================\n\nfunction mapEnrollmentPack(raw: {\n  id?: number;\n  title?: string;\n  slug?: string | null;\n  description?: string | null;\n  url?: string;\n  canonical_url?: string;\n  images?: { url?: string; alt?: string | null }[];\n}): enrollmentPacks.EnrollmentPack {\n  return {\n    id: raw.id ?? 0,\n    title: raw.title ?? \"\",\n    slug: raw.slug ?? null,\n    description: raw.description ?? null,\n    url: raw.url ?? null,\n    canonical_url: raw.canonical_url ?? null,\n    images: (raw.images ?? []).map((img) => ({\n      url: img.url ?? null,\n      alt: img.alt ?? null,\n    })),\n  };\n}\n\nfunction mapEnrollmentPacksMeta(\n  raw:\n    | NonNullable<\n        Awaited<ReturnType<typeof portalTenant.enrollmentPacksList>>\n      >[\"meta\"]\n    | undefined,\n): enrollmentPacks.EnrollmentPacksListResponse[\"meta\"] {\n  return {\n    request_id: raw?.request_id ?? null,\n    timestamp: raw?.timestamp ?? \"\",\n    pagination: raw?.pagination\n      ? {\n          cursor: raw.pagination.cursor ?? null,\n          limit: raw.pagination.limit,\n          next_cursor: raw.pagination.next_cursor ?? null,\n          prev_cursor: raw.pagination.prev_cursor ?? null,\n        }\n      : undefined,\n  };\n}\n\nfunction createRawEnrollmentPacksAdapter(\n  client: PortalTenantHeyApiClient,\n): ContentEnrollmentPacksApi {\n  return {\n    listEnrollmentPacks: async (params) => {\n      const response = await portalTenant.enrollmentPacksList({\n        client,\n        query: {\n          \"page[cursor]\": params?.cursor,\n          \"page[limit]\": params?.limit,\n        },\n      });\n      // BFF marks `id` as optional in its generated type; drop entries\n      // without one rather than mapping them to id=0 (which would silently\n      // misroute downstream playlist-item operations).\n      const packs = (response.enrollment_packs ?? [])\n        .filter((p): p is typeof p & { id: number } => typeof p.id === \"number\")\n        .map(mapEnrollmentPack);\n      return {\n        enrollment_packs: packs,\n        meta: mapEnrollmentPacksMeta(response.meta),\n      };\n    },\n\n    getEnrollmentPack: async (id) => {\n      const response = await portalTenant.enrollmentPacksShow({\n        client,\n        path: { id },\n      });\n      if (!response.enrollment_pack) {\n        throw new Error(`EnrollmentPack ${id} not found`);\n      }\n      return {\n        enrollment_pack: mapEnrollmentPack(response.enrollment_pack),\n        meta: mapEnrollmentPacksMeta(response.meta),\n      };\n    },\n  };\n}\n\n// ============================================================================\n// DAM Assets / Files — Raw BFF adapter (private)\n// ============================================================================\n\nfunction mapDamAsset(\n  raw: NonNullable<\n    Awaited<ReturnType<typeof portalTenantContent.dam_assets_list>>[\"assets\"]\n  >[number],\n): damAssets.DamAsset {\n  return {\n    id: raw.id ?? 0,\n    code: raw.code ?? \"\",\n    name: raw.name ?? \"\",\n    description: raw.description ?? null,\n    category: raw.category ?? null,\n    company: raw.company ?? null,\n    default_variant_id: raw.default_variant_id ?? null,\n    default_variant_url: raw.default_variant_url ?? null,\n    canonical_path: raw.canonical_path ?? null,\n    created_at: raw.created_at ?? \"\",\n    updated_at: raw.updated_at ?? \"\",\n  };\n}\n\nfunction mapDamAssetPath(\n  raw: NonNullable<\n    Awaited<\n      ReturnType<typeof portalTenantContent.dam_asset_paths_list>\n    >[\"asset_paths\"]\n  >[number],\n): damAssets.DamAssetPath {\n  return {\n    id: raw.id ?? 0,\n    asset_code: raw.asset_code ?? \"\",\n    path: raw.path ?? \"\",\n    created_at: raw.created_at ?? \"\",\n  };\n}\n\nfunction mapDamAssetsMeta(\n  raw: Awaited<ReturnType<typeof portalTenantContent.dam_assets_list>>[\"meta\"],\n): damAssets.DamAssetsListResponse[\"meta\"] {\n  return {\n    request_id: raw?.request_id ?? null,\n    timestamp: raw?.timestamp ?? \"\",\n    pagination: raw?.pagination\n      ? {\n          cursor: raw.pagination.cursor ?? null,\n          limit: raw.pagination.limit,\n          next_cursor: raw.pagination.next_cursor ?? null,\n          prev_cursor: raw.pagination.prev_cursor ?? null,\n        }\n      : undefined,\n  };\n}\n\nfunction createRawDamAssetsAdapter(\n  client: PortalTenantContentHeyApiClient,\n): ContentDamAssetsApi {\n  return {\n    listAssets: async (params) => {\n      const response = await portalTenantContent.dam_assets_list(client, {\n        \"page[cursor]\": params?.cursor,\n        \"page[limit]\": params?.limit,\n      });\n      return {\n        assets: (response.assets ?? []).map(mapDamAsset),\n        meta: mapDamAssetsMeta(response.meta),\n      };\n    },\n\n    createAsset: async (body) => {\n      const response = await portalTenantContent.dam_assets_create(client, {\n        asset: body,\n      });\n      return {\n        asset: mapDamAsset(response.asset ?? {}),\n        meta: mapDamAssetsMeta(response.meta),\n      };\n    },\n\n    listAssetPaths: async (assetCode, params) => {\n      const response = await portalTenantContent.dam_asset_paths_list(\n        client,\n        assetCode,\n        {\n          \"page[cursor]\": params?.cursor,\n          \"page[limit]\": params?.limit,\n        },\n      );\n      return {\n        asset_paths: (response.asset_paths ?? []).map(mapDamAssetPath),\n        meta: mapDamAssetsMeta(response.meta),\n      };\n    },\n\n    createAssetPath: async (assetCode, body) => {\n      const response = await portalTenantContent.dam_asset_paths_create(\n        client,\n        assetCode,\n        { asset_path: body },\n      );\n      return {\n        asset_path: mapDamAssetPath(response.asset_path ?? {}),\n        meta: mapDamAssetsMeta(response.meta),\n      };\n    },\n\n    discardAsset: async (assetCode) => {\n      const response = await portalTenantContent.dam_assets_discard(\n        client,\n        assetCode,\n      );\n      if (!response.asset) {\n        throw new Error(\"Invalid DAM asset discard response.\");\n      }\n      return {\n        asset: mapDamAsset(response.asset),\n        meta: mapDamAssetsMeta(response.meta),\n      };\n    },\n\n    deleteAsset: async (assetCode) => {\n      const response = await portalTenantContent.dam_assets_destroy(\n        client,\n        assetCode,\n      );\n      return {\n        asset: { code: response.asset?.code ?? assetCode },\n        meta: mapDamAssetsMeta(response.meta),\n      };\n    },\n  };\n}\n\n// ============================================================================\n// Content favorites — authenticated member only\n// ============================================================================\n\nfunction isContentFavoriteType(value: string): value is ContentFavoriteType {\n  return CONTENT_FAVORITE_TYPES.some((candidate) => candidate === value);\n}\n\nfunction createContentFavoritesAdapter(\n  client: PortalTenantContentHeyApiClient,\n): ContentFavoritesApi {\n  return {\n    toggleFavorite: async (input) => {\n      const response = await portalTenantContent.favorites_toggle(\n        client,\n        input,\n      );\n      const isFavorited = response.favorite?.is_favorited;\n      if (typeof isFavorited !== \"boolean\") {\n        throw new Error(\"Invalid content favorite toggle response.\");\n      }\n      return {\n        favoriteable_id: input.favoriteable_id,\n        favoriteable_type: input.favoriteable_type,\n        is_favorited: isFavorited,\n      } satisfies ContentFavorite;\n    },\n  };\n}\n\n// ============================================================================\n// Files — ShareablesApi-compatible adapter (private)\n// ============================================================================\n\nfunction createFileResourcesAdapter(\n  client: PortalTenantContentHeyApiClient,\n): FileResourcesApi {\n  const portAdapter = createRawDamAssetsAdapter(client);\n  const cursorByPage = new Map<number, string>();\n\n  return {\n    getFileResources: async (params) => {\n      const pageNumber = params?.pageParam ? Number(params.pageParam) : 1;\n      const pageSize = params?.pageSize ? Number(params.pageSize) : 25;\n      const cursor = pageNumber > 1 ? cursorByPage.get(pageNumber) : undefined;\n\n      const response = await portAdapter.listAssets({\n        cursor,\n        limit: pageSize,\n      });\n\n      const nextCursor = response.meta.pagination?.next_cursor;\n      if (nextCursor) {\n        cursorByPage.set(pageNumber + 1, nextCursor);\n      }\n\n      const fileResources: shareables.FileResource[] = response.assets.map(\n        (asset) => ({\n          id: asset.id,\n          alt_text: asset.name,\n          url: asset.default_variant_url ?? \"\",\n          filename: asset.name,\n          content_type: \"application/octet-stream\",\n          content_size: 0,\n          handle: asset.code,\n          dam_asset_code: asset.code,\n          preview_image_url: asset.default_variant_url ?? \"\",\n          created_at: asset.created_at,\n          updated_at: asset.updated_at ?? \"\",\n          relateable_type: null,\n          relateable_id: null,\n          content: null,\n        }),\n      );\n\n      const hasNextPage = !!nextCursor;\n\n      return {\n        file_resources: fileResources,\n        meta: {\n          total_count: fileResources.length,\n          per_page: pageSize,\n          current_page: pageNumber,\n          total_pages: hasNextPage ? pageNumber + 1 : pageNumber,\n        },\n      };\n    },\n  };\n}\n\n// ============================================================================\n// Metrics — Raw BFF adapter (private)\n// ============================================================================\n\nfunction mapMetricsMeta(\n  raw:\n    | Awaited<\n        ReturnType<typeof portalTenantContent.content_media_by_visits>\n      >[\"meta\"]\n    | undefined,\n): metrics.VisitedResponse[\"meta\"] {\n  if (!raw) return undefined;\n  return {\n    request_id: raw.request_id ?? null,\n    timestamp: raw.timestamp ?? \"\",\n    pagination: raw.pagination\n      ? {\n          cursor: raw.pagination.cursor ?? null,\n          limit: raw.pagination.limit,\n          next_cursor: raw.pagination.next_cursor ?? null,\n          prev_cursor: raw.pagination.prev_cursor ?? null,\n        }\n      : undefined,\n  };\n}\n\nfunction createMetricsAdapter(\n  client: PortalTenantContentHeyApiClient,\n): ContentMetricsApi {\n  return {\n    listMediaVisited: async (params) => {\n      const response = await portalTenantContent.content_media_by_visits(\n        client,\n        {\n          period: params?.period,\n          limit: params?.limit,\n          language_iso: params?.language_iso,\n        },\n      );\n      return {\n        resources: response.resources ?? [],\n        meta: mapMetricsMeta(response.meta),\n      };\n    },\n\n    listMediaShareVisited: async (params) => {\n      const response = await portalTenantContent.content_media_by_shares(\n        client,\n        {\n          period: params?.period,\n          limit: params?.limit,\n          language_iso: params?.language_iso,\n        },\n      );\n      return {\n        resources: response.resources ?? [],\n        meta: mapMetricsMeta(response.meta),\n      };\n    },\n\n    listPlaylistsVisited: async (params) => {\n      const response = await portalTenantContent.content_playlists_by_visits(\n        client,\n        {\n          period: params?.period,\n          limit: params?.limit,\n        },\n      );\n      return {\n        resources: response.resources ?? [],\n        meta: mapMetricsMeta(response.meta),\n      };\n    },\n\n    listPlaylistsShareVisited: async (params) => {\n      const response = await portalTenantContent.content_playlists_by_shares(\n        client,\n        { period: params?.period, limit: params?.limit },\n      );\n      return {\n        resources: response.resources ?? [],\n        meta: mapMetricsMeta(response.meta),\n      };\n    },\n\n    listPagesVisited: async (params) => {\n      const response = await portalTenantContent.content_pages_by_visits(\n        client,\n        {\n          period: params?.period,\n          limit: params?.limit,\n          language_iso: params?.language_iso,\n        },\n      );\n      return {\n        resources: response.resources ?? [],\n        meta: mapMetricsMeta(response.meta),\n      };\n    },\n\n    listPagesShareVisited: async (params) => {\n      const response = await portalTenantContent.content_pages_by_shares(\n        client,\n        {\n          period: params?.period,\n          limit: params?.limit,\n          language_iso: params?.language_iso,\n        },\n      );\n      return {\n        resources: response.resources ?? [],\n        meta: mapMetricsMeta(response.meta),\n      };\n    },\n  };\n}\n\n// ============================================================================\n// Product Media (private)\n// ============================================================================\n\n/**\n * Narrow interface for the product media endpoint. Matches\n * PortalProductsApi.getProductMedia without importing the full products-core\n * dependency graph, keeping the dependency graph clean.\n */\nexport interface ProductMediaSource {\n  getProductMedia(productId: string | number): Promise<{\n    media: ReadonlyArray<{\n      id?: number;\n      title?: string;\n      media_type?: string;\n      url?: string;\n    }>;\n  }>;\n}\n\nfunction mapProductMedia(raw: {\n  id?: number;\n  title?: string;\n  media_type?: string;\n  url?: string;\n}): shareables.ProductMedia {\n  const isVideo = raw.media_type === \"video\";\n  const isPdf = raw.media_type === \"pdf\" || raw.media_type === \"document\";\n  return {\n    id: raw.id ?? 0,\n    slug: null,\n    title: raw.title ?? \"\",\n    kind: isVideo ? \"video\" : isPdf ? \"pdf\" : \"image\",\n    media_type: raw.media_type ?? \"image\",\n    media_format: raw.media_type ?? \"image\",\n    image_url: !isVideo && !isPdf ? (raw.url ?? null) : null,\n    video_url: isVideo ? (raw.url ?? null) : null,\n    pdf_url: isPdf ? (raw.url ?? null) : null,\n    powerpoint_url: null,\n    duration: 0,\n    description: null,\n    subtitles: {},\n    comments_count: 0,\n  };\n}\n\nfunction createProductMediaAdapter(\n  source: ProductMediaSource,\n): ProductMediaApi {\n  return {\n    getProductMedia: async (productId: number) => {\n      const response = await source.getProductMedia(productId);\n      return {\n        media: (response.media ?? []).map(mapProductMedia),\n      };\n    },\n  };\n}\n\n// ============================================================================\n// Internal test helpers (consumed by tests only — not re-exported from index.ts)\n// ============================================================================\n\n/** @internal — For tests only. */\nexport const _createRawMediaAdapter: typeof createRawMediaAdapter =\n  createRawMediaAdapter;\n/** @internal — For tests only. */\nexport const _createRawDamAssetsAdapter: typeof createRawDamAssetsAdapter =\n  createRawDamAssetsAdapter;\n/** @internal — For tests only. */\nexport const _createRawSharesAdapter: typeof createRawSharesAdapter =\n  createRawSharesAdapter;\n/** @internal — For tests only. */\nexport const _createMetricsAdapter: typeof createMetricsAdapter =\n  createMetricsAdapter;\n/** @internal — For tests only. */\nexport const _createRawPagesAdapter: typeof createRawPagesAdapter =\n  createRawPagesAdapter;\n\n// ============================================================================\n// Public exports\n// ============================================================================\n\n/**\n * Creates a composite ContentDomainApi backed by the portal-tenant Content\n * BFF endpoints. Follows the same pattern as\n * `createPortalContactsDomainApiAdapter`.\n */\nexport function createPortalContentDomainApiAdapter(\n  client: PortalTenantContentHeyApiClient,\n  productsApi: ProductMediaSource,\n): ContentDomainApi {\n  return {\n    media: createMediaAdapter(client),\n    playlists: createPlaylistsAdapter(client),\n    fileResources: createFileResourcesAdapter(client),\n    share: createShareAdapter(client),\n    productMedia: createProductMediaAdapter(productsApi),\n    metrics: createMetricsAdapter(client),\n    pages: createRawPagesAdapter(client),\n  };\n}\n\n/**\n * Creates a ContentPlaylistsApi (the port-level playlists adapter) for\n * operations that aren't part of the shareables PlaylistsApi — e.g.\n * `deletePlaylist`. Exposed separately because ContentDomainApi.playlists\n * is the higher-level shareables PlaylistsApi.\n */\nexport function createPortalContentPlaylistsAdapter(\n  client: PortalTenantContentHeyApiClient,\n): ContentPlaylistsApi {\n  return createRawPlaylistsAdapter(client);\n}\n\n/** Creates the port-level media adapter for SDK-owned capability hosts. */\nexport function createPortalContentMediaAdapter(\n  client: PortalTenantContentHeyApiClient,\n): ContentMediaApi {\n  return createRawMediaAdapter(client);\n}\n\n/** Creates the port-level shares adapter for SDK-owned capability hosts. */\nexport function createPortalContentSharesAdapter(\n  client: PortalTenantContentHeyApiClient,\n): ContentSharesApi {\n  return createRawSharesAdapter(client);\n}\n\n/** Creates the port-level DAM adapter without exposing file-picker operations. */\nexport function createPortalContentDamAssetsAdapter(\n  client: PortalTenantContentHeyApiClient,\n): ContentDamAssetsApi {\n  return createRawDamAssetsAdapter(client);\n}\n\n/** Creates the authenticated member's narrow content-favorites adapter. */\nexport function createPortalContentFavoritesAdapter(\n  client: PortalTenantContentHeyApiClient,\n): ContentFavoritesApi {\n  return createContentFavoritesAdapter(client);\n}\n\n/**\n * Creates a ContentPagesApi (the port-level pages adapter) for screens that\n * need to list/show pages outside of ShareablesApiProvider — e.g. the\n * playlist editor's content picker. Mirrors createPortalContentPlaylistsAdapter.\n */\nexport function createPortalContentPagesAdapter(\n  client: PortalTenantContentHeyApiClient,\n): ContentPagesApi {\n  return createRawPagesAdapter(client);\n}\n\n/**\n * Creates a ContentEnrollmentPacksApi adapter for screens that need to\n * list/show enrollment packs outside of ShareablesApiProvider — e.g. the\n * playlist editor's content picker. Backed by the portal-tenant\n * `/api/enrollment_packs` endpoint.\n */\nexport function createPortalContentEnrollmentPacksAdapter(\n  client: PortalTenantHeyApiClient,\n): ContentEnrollmentPacksApi {\n  return createRawEnrollmentPacksAdapter(client);\n}\n\n/**\n * Toggles a favorite entry on a given shareable (Medium / Playlist /\n * Product / etc.) via the portal-tenant BFF's /favorites/toggle endpoint.\n * Returns the new is_favorited state reported by the backend.\n */\nexport async function toggleFavorite(\n  client: PortalTenantContentHeyApiClient,\n  favoriteableId: number,\n  favoriteableType: string,\n): Promise<{ is_favorited: boolean }> {\n  const canonicalType =\n    favoriteableType === \"Library\" ? \"Playlist\" : favoriteableType;\n  if (!isContentFavoriteType(canonicalType)) {\n    throw new Error(`Unsupported content favorite type: \"${favoriteableType}\"`);\n  }\n  const favorite = await createContentFavoritesAdapter(client).toggleFavorite({\n    favoriteable_id: favoriteableId,\n    favoriteable_type: canonicalType,\n  });\n  return { is_favorited: favorite.is_favorited };\n}\n","import {\n  createContext,\n  type ReactElement,\n  type ReactNode,\n  use,\n  useMemo,\n} from \"react\";\nimport { ShareablesApiProvider } from \"@fluid-app/shareables-core\";\nimport type {\n  ContentMediaApi,\n  ContentMediaProductsApi,\n} from \"@fluid-app/shareables-core/media-api\";\nimport type { ContentPagesApi } from \"@fluid-app/shareables-core/pages-api\";\nimport type { ContentEnrollmentPacksApi } from \"@fluid-app/shareables-core/enrollment-packs-api\";\nimport type { ContentPlaylistsApi } from \"@fluid-app/shareables-core/playlists-api\";\nimport type { ContentSharesApi } from \"@fluid-app/shareables-core/shares-api\";\nimport type { ContentDamAssetsApi } from \"@fluid-app/shareables-core/dam-assets-api\";\nimport type { ContentFavoritesApi } from \"@fluid-app/shareables-core/favorites-api\";\nimport type { PortalProductsApi } from \"@fluid-app/products-core\";\nimport { FilePickerApiProvider } from \"@fluid-app/file-picker-core\";\nimport { usePortalProductsApi } from \"@fluid-app/products-core\";\nimport { createFilePickerApiAdapter } from \"../adapters/file-picker-api-adapter\";\nimport { usePortalTenantClient } from \"../providers/PortalTenantClientProvider\";\nimport { usePortalTenantContentClient } from \"../providers/PortalTenantContentClientProvider\";\nimport {\n  createPortalContentDomainApiAdapter,\n  createPortalContentDamAssetsAdapter,\n  createPortalContentEnrollmentPacksAdapter,\n  createPortalContentFavoritesAdapter,\n  createPortalContentMediaAdapter,\n  createPortalContentPagesAdapter,\n  createPortalContentPlaylistsAdapter,\n  createPortalContentSharesAdapter,\n  createPortalTenantMediaProductsAdapter,\n} from \"../adapters/content-api-adapter\";\n\n/**\n * Extra context values that screens need beyond ContentDomainApi.\n * ContentDomainApi flows through ShareablesApiProvider; these extras\n * are available via usePortalContentContext().\n */\nexport interface PortalContentContext {\n  /** The products adapter — exposed so screens can call listProducts / getProduct\n   *  without a separate usePortalProductsApi() import. */\n  productsApi: PortalProductsApi;\n  /** Exact BFF media port used by SDK-owned capability hosts. */\n  mediaAdapter: ContentMediaApi;\n  /** Port-level playlists adapter for operations outside ShareablesApiProvider\n   *  (e.g. deletePlaylist). */\n  playlistsAdapter: ContentPlaylistsApi;\n  /** Port-level pages adapter for operations outside ShareablesApiProvider\n   *  (e.g. picker source for the playlist editor). */\n  pagesAdapter: ContentPagesApi;\n  /** Port-level enrollment-packs adapter — backed by the portal-tenant\n   *  /api/enrollment_packs endpoint. Used by the playlist editor's content\n   *  picker. */\n  enrollmentPacksAdapter: ContentEnrollmentPacksApi;\n  /** Media products adapter for tagging products on media. */\n  mediaProductsAdapter: ContentMediaProductsApi;\n  /** Exact BFF shares port used by SDK-owned capability hosts. */\n  sharesAdapter: ContentSharesApi;\n  /** Narrow DAM port that excludes upload, proxy, and Unsplash operations. */\n  damAssetsAdapter: ContentDamAssetsApi;\n  /** Narrow authenticated-member content favorite mutations. */\n  favoritesAdapter: ContentFavoritesApi;\n}\n\nconst ContentContext = createContext<PortalContentContext | null>(null);\n\nexport function usePortalContentContext(): PortalContentContext {\n  const ctx = use(ContentContext);\n  if (!ctx) {\n    throw new Error(\n      \"usePortalContentContext must be used within a <PortalContentApiProvider>\",\n    );\n  }\n  return ctx;\n}\n\n/**\n * Provides all content-domain adapters (media, playlists, shares,\n * fileResources, productMedia) via ShareablesApiProvider, plus extra\n * context values available through usePortalContentContext().\n *\n * **Required ancestor:** `<PortalProductsApiProvider>` must appear above\n * this in the tree — it supplies the `PortalProductsApi` consumed via\n * `usePortalProductsApi()` for product-media bridging.\n */\nexport function PortalContentApiProvider({\n  children,\n}: {\n  children: ReactNode;\n}): ReactElement {\n  const portalTenantClient = usePortalTenantClient();\n  const contentClient = usePortalTenantContentClient();\n  const productsApi = usePortalProductsApi();\n\n  const contentApi = useMemo(\n    () => createPortalContentDomainApiAdapter(contentClient, productsApi),\n    [contentClient, productsApi],\n  );\n\n  const playlistsAdapter = useMemo(\n    () => createPortalContentPlaylistsAdapter(contentClient),\n    [contentClient],\n  );\n\n  const mediaAdapter = useMemo(\n    () => createPortalContentMediaAdapter(contentClient),\n    [contentClient],\n  );\n\n  const pagesAdapter = useMemo(\n    () => createPortalContentPagesAdapter(contentClient),\n    [contentClient],\n  );\n\n  const enrollmentPacksAdapter = useMemo(\n    () => createPortalContentEnrollmentPacksAdapter(portalTenantClient),\n    [portalTenantClient],\n  );\n\n  const mediaProductsAdapter = useMemo(\n    () => createPortalTenantMediaProductsAdapter(contentClient),\n    [contentClient],\n  );\n\n  const sharesAdapter = useMemo(\n    () => createPortalContentSharesAdapter(contentClient),\n    [contentClient],\n  );\n\n  const damAssetsAdapter = useMemo(\n    () => createPortalContentDamAssetsAdapter(contentClient),\n    [contentClient],\n  );\n\n  const favoritesAdapter = useMemo(\n    () => createPortalContentFavoritesAdapter(contentClient),\n    [contentClient],\n  );\n\n  const filePickerApi = useMemo(\n    () => createFilePickerApiAdapter(contentClient),\n    [contentClient],\n  );\n\n  const ctx = useMemo(\n    () => ({\n      productsApi,\n      mediaAdapter,\n      playlistsAdapter,\n      pagesAdapter,\n      enrollmentPacksAdapter,\n      mediaProductsAdapter,\n      sharesAdapter,\n      damAssetsAdapter,\n      favoritesAdapter,\n    }),\n    [\n      productsApi,\n      mediaAdapter,\n      playlistsAdapter,\n      pagesAdapter,\n      enrollmentPacksAdapter,\n      mediaProductsAdapter,\n      sharesAdapter,\n      damAssetsAdapter,\n      favoritesAdapter,\n    ],\n  );\n\n  return (\n    <ContentContext.Provider value={ctx}>\n      <ShareablesApiProvider value={contentApi}>\n        <FilePickerApiProvider value={filePickerApi}>\n          {children}\n        </FilePickerApiProvider>\n      </ShareablesApiProvider>\n    </ContentContext.Provider>\n  );\n}\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\nvar ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';\n\nmodule.exports = ReactPropTypesSecret;\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\nvar ReactPropTypesSecret = require('./lib/ReactPropTypesSecret');\n\nfunction emptyFunction() {}\nfunction emptyFunctionWithReset() {}\nemptyFunctionWithReset.resetWarningCache = emptyFunction;\n\nmodule.exports = function() {\n  function shim(props, propName, componentName, location, propFullName, secret) {\n    if (secret === ReactPropTypesSecret) {\n      // It is still safe when called from React.\n      return;\n    }\n    var err = new Error(\n      'Calling PropTypes validators directly is not supported by the `prop-types` package. ' +\n      'Use PropTypes.checkPropTypes() to call them. ' +\n      'Read more at http://fb.me/use-check-prop-types'\n    );\n    err.name = 'Invariant Violation';\n    throw err;\n  };\n  shim.isRequired = shim;\n  function getShim() {\n    return shim;\n  };\n  // Important!\n  // Keep this list in sync with production version in `./factoryWithTypeCheckers.js`.\n  var ReactPropTypes = {\n    array: shim,\n    bigint: shim,\n    bool: shim,\n    func: shim,\n    number: shim,\n    object: shim,\n    string: shim,\n    symbol: shim,\n\n    any: shim,\n    arrayOf: getShim,\n    element: shim,\n    elementType: shim,\n    instanceOf: getShim,\n    node: shim,\n    objectOf: getShim,\n    oneOf: getShim,\n    oneOfType: getShim,\n    shape: getShim,\n    exact: getShim,\n\n    checkPropTypes: emptyFunctionWithReset,\n    resetWarningCache: emptyFunction\n  };\n\n  ReactPropTypes.PropTypes = ReactPropTypes;\n\n  return ReactPropTypes;\n};\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nif (process.env.NODE_ENV !== 'production') {\n  var ReactIs = require('react-is');\n\n  // By explicitly using `prop-types` you are opting into new development behavior.\n  // http://fb.me/prop-types-in-prod\n  var throwOnDirectAccess = true;\n  module.exports = require('./factoryWithTypeCheckers')(ReactIs.isElement, throwOnDirectAccess);\n} else {\n  // By explicitly using `prop-types` you are opting into new production behavior.\n  // http://fb.me/prop-types-in-prod\n  module.exports = require('./factoryWithThrowingShims')();\n}\n"],"x_google_ignoreList":[23,24,25],"mappings":"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"}