@fluid-app/portal-sdk 0.1.147 → 0.1.149

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/{ContactsScreen-CRwQbaPg.mjs → ContactsScreen-DtABz7O7.mjs} +2 -2
  2. package/dist/ContactsScreen-DtABz7O7.mjs.map +1 -0
  3. package/dist/{ContactsScreen-TDXVil2l.cjs → ContactsScreen-DuKE5ruf.cjs} +1 -1
  4. package/dist/{ContactsScreen-D7EBGdu1.cjs → ContactsScreen-psnV3fcP.cjs} +2 -2
  5. package/dist/ContactsScreen-psnV3fcP.cjs.map +1 -0
  6. package/dist/{MessagingScreen-D6jmQG0E.cjs → MessagingScreen-B5lqBpVo.cjs} +1 -1
  7. package/dist/{MessagingScreen-BG-eib6U.cjs → MessagingScreen-DSU_xyHK.cjs} +2 -2
  8. package/dist/MessagingScreen-DSU_xyHK.cjs.map +1 -0
  9. package/dist/{MessagingScreen-Bt0wmxDg.mjs → MessagingScreen-gbTy8V_o.mjs} +2 -2
  10. package/dist/MessagingScreen-gbTy8V_o.mjs.map +1 -0
  11. package/dist/{ProductsScreen-D6grDsLg.mjs → ProductsScreen--hkyw5c3.mjs} +9 -16
  12. package/dist/ProductsScreen--hkyw5c3.mjs.map +1 -0
  13. package/dist/{ProductsScreen-BYziWeSs.cjs → ProductsScreen-C8wwsfu0.cjs} +14 -21
  14. package/dist/ProductsScreen-C8wwsfu0.cjs.map +1 -0
  15. package/dist/{ProductsScreen-V6jOhd4m.cjs → ProductsScreen-DG_SMNs5.cjs} +2 -2
  16. package/dist/{ProductsScreen-CMpMLotN.mjs → ProductsScreen-IbgDLX51.mjs} +7 -2
  17. package/dist/{ShareablesScreen-BpOu1VpJ.cjs → ShareablesScreen-B0JMhiKA.cjs} +41 -26
  18. package/dist/ShareablesScreen-B0JMhiKA.cjs.map +1 -0
  19. package/dist/{ShareablesScreen-7W63bXCs.mjs → ShareablesScreen-B8ZsEkgi.mjs} +32 -17
  20. package/dist/ShareablesScreen-B8ZsEkgi.mjs.map +1 -0
  21. package/dist/{ShareablesScreen-DvCp2TyE.mjs → ShareablesScreen-C2zLeoy7.mjs} +8 -2
  22. package/dist/{ShareablesScreen-Do-aNX-x.cjs → ShareablesScreen-Caf2fI3S.cjs} +2 -2
  23. package/dist/index.cjs +13 -13
  24. package/dist/index.d.cts.map +1 -1
  25. package/dist/index.d.mts.map +1 -1
  26. package/dist/index.mjs +13 -13
  27. package/dist/{use-account-clients-DdEdLQc1.mjs → use-portal-shareables-api-CCRQARQM.mjs} +60 -28
  28. package/dist/use-portal-shareables-api-CCRQARQM.mjs.map +1 -0
  29. package/dist/{use-account-clients-Db7XdaFV.cjs → use-portal-shareables-api-CwSezl14.cjs} +65 -57
  30. package/dist/use-portal-shareables-api-CwSezl14.cjs.map +1 -0
  31. package/package.json +18 -17
  32. package/dist/ContactsScreen-CRwQbaPg.mjs.map +0 -1
  33. package/dist/ContactsScreen-D7EBGdu1.cjs.map +0 -1
  34. package/dist/MessagingScreen-BG-eib6U.cjs.map +0 -1
  35. package/dist/MessagingScreen-Bt0wmxDg.mjs.map +0 -1
  36. package/dist/ProductsScreen-BYziWeSs.cjs.map +0 -1
  37. package/dist/ProductsScreen-D6grDsLg.mjs.map +0 -1
  38. package/dist/ShareablesScreen-7W63bXCs.mjs.map +0 -1
  39. package/dist/ShareablesScreen-BpOu1VpJ.cjs.map +0 -1
  40. package/dist/use-account-clients-Db7XdaFV.cjs.map +0 -1
  41. package/dist/use-account-clients-DdEdLQc1.mjs.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"ProductsScreen-BYziWeSs.cjs","names":["useSdkClient","usePortalProductsClient","usePortalTenantClient","useCurrentUser","useAppNavigation","createPortalTenantMediaShareablesAdapter","createPortalTenantPlaylistsShareablesAdapter","createPortalTenantFilesShareablesAdapter","createPortalTenantSharesShareablesAdapter","createPortalTenantProductMediaShareablesAdapter","ShareablesCoreProvider","ShareablesApiProvider","ShareablesUIProvider","ProductsApp"],"sources":["../src/screens/ProductsScreen.tsx"],"sourcesContent":["import { useCallback, useMemo, type ComponentProps } from \"react\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"../types\";\nimport type { WidgetPropertySchema } from \"../registries/property-schema-types\";\nimport {\n ShareablesCoreProvider,\n ShareablesApiProvider,\n} from \"@fluid-app/shareables-core\";\nimport { ShareablesUIProvider, ProductsApp } from \"@fluid-app/shareables-ui\";\nimport {\n createPortalTenantMediaShareablesAdapter,\n createPortalTenantPlaylistsShareablesAdapter,\n createPortalTenantFilesShareablesAdapter,\n createPortalTenantSharesShareablesAdapter,\n createPortalTenantProductMediaShareablesAdapter,\n} from \"@fluid-app/shareables-api-client\";\nimport { useCurrentUser } from \"../hooks/use-current-user\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\nimport { useSdkClient } from \"../account/use-account-clients\";\nimport { usePortalTenantClient } from \"../providers/PortalTenantClientProvider\";\nimport { usePortalProductsClient } from \"../products/use-portal-products-client\";\n\ntype ProductsScreenProps = ComponentProps<\"div\"> & {\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n};\n\nexport function ProductsScreen({\n /* eslint-disable @typescript-eslint/no-unused-vars -- destructured to exclude from divProps spread */\n background,\n textColor,\n accentColor,\n padding,\n borderRadius,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n ...divProps\n}: ProductsScreenProps): React.JSX.Element {\n const domainClient = useSdkClient();\n const portalProductsApi = usePortalProductsClient();\n const portalTenantClient = usePortalTenantClient();\n const { data: userData } = useCurrentUser();\n const { currentSlug, navigate } = useAppNavigation();\n\n const fetchProducts = useCallback(\n async (search: string, cursor?: string, limit?: number) => {\n if (search) {\n return portalProductsApi.searchProducts(search, { cursor, limit });\n }\n return portalProductsApi.listProducts({ cursor, limit });\n },\n [portalProductsApi],\n );\n\n const fetchProduct = useCallback(\n async (id: string | number) => portalProductsApi.getProduct(id),\n [portalProductsApi],\n );\n\n // Extract product ID from slug: \"products/123\" → \"123\"\n const productId = useMemo(() => {\n const match = currentSlug.match(/^products\\/(.+)/);\n return match?.[1] ?? null;\n }, [currentSlug]);\n\n const handleSelectProduct = useCallback(\n (id: string) => {\n navigate(`products/${id}`);\n },\n [navigate],\n );\n\n const handleBack = useCallback(() => {\n navigate(\"products\");\n }, [navigate]);\n\n const coreConfig = useMemo(\n () => ({\n client: domainClient,\n user: userData ? { id: userData.id } : null,\n repContext: true,\n }),\n [domainClient, userData],\n );\n\n const mediaAdapter = useMemo(\n () => createPortalTenantMediaShareablesAdapter(portalTenantClient),\n [portalTenantClient],\n );\n const playlistsAdapter = useMemo(\n () => createPortalTenantPlaylistsShareablesAdapter(portalTenantClient),\n [portalTenantClient],\n );\n const filesAdapter = useMemo(\n () => createPortalTenantFilesShareablesAdapter(portalTenantClient),\n [portalTenantClient],\n );\n const sharesAdapter = useMemo(\n () => createPortalTenantSharesShareablesAdapter(portalTenantClient),\n [portalTenantClient],\n );\n const productMediaAdapter = useMemo(\n () => createPortalTenantProductMediaShareablesAdapter(portalProductsApi),\n [portalProductsApi],\n );\n\n const uiConfig = useMemo(\n () => ({\n user: userData\n ? {\n id: userData.id,\n company: userData.company\n ? { logo_url: userData.company.logo_url }\n : null,\n }\n : undefined,\n basePath: \"\",\n navigate: (path: string) => {\n navigate(path);\n },\n showToast: (opts: {\n title: string;\n type: \"success\" | \"error\" | \"warning\";\n }) => {\n console.log(`[Products] ${opts.type}: ${opts.title}`);\n },\n }),\n [userData, navigate],\n );\n\n return (\n <div {...divProps} className={`h-full ${divProps.className ?? \"\"}`}>\n <ShareablesCoreProvider config={coreConfig}>\n <ShareablesApiProvider\n media={mediaAdapter}\n playlists={playlistsAdapter}\n fileResources={filesAdapter}\n share={sharesAdapter}\n productMedia={productMediaAdapter}\n >\n <ShareablesUIProvider config={uiConfig}>\n <ProductsApp\n countryCode={userData?.country?.iso}\n companyLogoUrl={userData?.company?.logo_url}\n fetchProducts={fetchProducts}\n fetchProduct={fetchProduct}\n productId={productId}\n onSelectProduct={handleSelectProduct}\n onBack={handleBack}\n />\n </ShareablesUIProvider>\n </ShareablesApiProvider>\n </ShareablesCoreProvider>\n </div>\n );\n}\n\nexport const productsScreenPropertySchema: WidgetPropertySchema = {\n widgetType: \"ProductsScreen\",\n displayName: \"Products Screen\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ProductsScreen-D6grDsLg.mjs","names":[],"sources":["../src/screens/ProductsScreen.tsx"],"sourcesContent":["import { useCallback, useMemo, type ComponentProps } from \"react\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"../types\";\nimport type { WidgetPropertySchema } from \"../registries/property-schema-types\";\nimport {\n ShareablesCoreProvider,\n ShareablesApiProvider,\n} from \"@fluid-app/shareables-core\";\nimport { ShareablesUIProvider, ProductsApp } from \"@fluid-app/shareables-ui\";\nimport {\n createPortalTenantMediaShareablesAdapter,\n createPortalTenantPlaylistsShareablesAdapter,\n createPortalTenantFilesShareablesAdapter,\n createPortalTenantSharesShareablesAdapter,\n createPortalTenantProductMediaShareablesAdapter,\n} from \"@fluid-app/shareables-api-client\";\nimport { useCurrentUser } from \"../hooks/use-current-user\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\nimport { useSdkClient } from \"../account/use-account-clients\";\nimport { usePortalTenantClient } from \"../providers/PortalTenantClientProvider\";\nimport { usePortalProductsClient } from \"../products/use-portal-products-client\";\n\ntype ProductsScreenProps = ComponentProps<\"div\"> & {\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n};\n\nexport function ProductsScreen({\n /* eslint-disable @typescript-eslint/no-unused-vars -- destructured to exclude from divProps spread */\n background,\n textColor,\n accentColor,\n padding,\n borderRadius,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n ...divProps\n}: ProductsScreenProps): React.JSX.Element {\n const domainClient = useSdkClient();\n const portalProductsApi = usePortalProductsClient();\n const portalTenantClient = usePortalTenantClient();\n const { data: userData } = useCurrentUser();\n const { currentSlug, navigate } = useAppNavigation();\n\n const fetchProducts = useCallback(\n async (search: string, cursor?: string, limit?: number) => {\n if (search) {\n return portalProductsApi.searchProducts(search, { cursor, limit });\n }\n return portalProductsApi.listProducts({ cursor, limit });\n },\n [portalProductsApi],\n );\n\n const fetchProduct = useCallback(\n async (id: string | number) => portalProductsApi.getProduct(id),\n [portalProductsApi],\n );\n\n // Extract product ID from slug: \"products/123\" → \"123\"\n const productId = useMemo(() => {\n const match = currentSlug.match(/^products\\/(.+)/);\n return match?.[1] ?? null;\n }, [currentSlug]);\n\n const handleSelectProduct = useCallback(\n (id: string) => {\n navigate(`products/${id}`);\n },\n [navigate],\n );\n\n const handleBack = useCallback(() => {\n navigate(\"products\");\n }, [navigate]);\n\n const coreConfig = useMemo(\n () => ({\n client: domainClient,\n user: userData ? { id: userData.id } : null,\n repContext: true,\n }),\n [domainClient, userData],\n );\n\n const mediaAdapter = useMemo(\n () => createPortalTenantMediaShareablesAdapter(portalTenantClient),\n [portalTenantClient],\n );\n const playlistsAdapter = useMemo(\n () => createPortalTenantPlaylistsShareablesAdapter(portalTenantClient),\n [portalTenantClient],\n );\n const filesAdapter = useMemo(\n () => createPortalTenantFilesShareablesAdapter(portalTenantClient),\n [portalTenantClient],\n );\n const sharesAdapter = useMemo(\n () => createPortalTenantSharesShareablesAdapter(portalTenantClient),\n [portalTenantClient],\n );\n const productMediaAdapter = useMemo(\n () => createPortalTenantProductMediaShareablesAdapter(portalProductsApi),\n [portalProductsApi],\n );\n\n const uiConfig = useMemo(\n () => ({\n user: userData\n ? {\n id: userData.id,\n company: userData.company\n ? { logo_url: userData.company.logo_url }\n : null,\n }\n : undefined,\n basePath: \"\",\n navigate: (path: string) => {\n navigate(path);\n },\n showToast: (opts: {\n title: string;\n type: \"success\" | \"error\" | \"warning\";\n }) => {\n console.log(`[Products] ${opts.type}: ${opts.title}`);\n },\n }),\n [userData, navigate],\n );\n\n return (\n <div {...divProps} className={`h-full ${divProps.className ?? \"\"}`}>\n <ShareablesCoreProvider config={coreConfig}>\n <ShareablesApiProvider\n media={mediaAdapter}\n playlists={playlistsAdapter}\n fileResources={filesAdapter}\n share={sharesAdapter}\n productMedia={productMediaAdapter}\n >\n <ShareablesUIProvider config={uiConfig}>\n <ProductsApp\n countryCode={userData?.country?.iso}\n companyLogoUrl={userData?.company?.logo_url}\n fetchProducts={fetchProducts}\n fetchProduct={fetchProduct}\n productId={productId}\n onSelectProduct={handleSelectProduct}\n onBack={handleBack}\n />\n </ShareablesUIProvider>\n </ShareablesApiProvider>\n </ShareablesCoreProvider>\n </div>\n );\n}\n\nexport const productsScreenPropertySchema: WidgetPropertySchema = {\n widgetType: \"ProductsScreen\",\n displayName: \"Products Screen\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":";;;;;;;;AAkCA,SAAgB,eAAe,EAE7B,YACA,WACA,aACA,SACA,cAEA,GAAG,YACsC;CACzC,MAAM,eAAe,cAAc;CACnC,MAAM,oBAAoB,yBAAyB;CACnD,MAAM,qBAAqB,uBAAuB;CAClD,MAAM,EAAE,MAAM,aAAa,gBAAgB;CAC3C,MAAM,EAAE,aAAa,aAAa,kBAAkB;CAEpD,MAAM,gBAAgB,YACpB,OAAO,QAAgB,QAAiB,UAAmB;AACzD,MAAI,OACF,QAAO,kBAAkB,eAAe,QAAQ;GAAE;GAAQ;GAAO,CAAC;AAEpE,SAAO,kBAAkB,aAAa;GAAE;GAAQ;GAAO,CAAC;IAE1D,CAAC,kBAAkB,CACpB;CAED,MAAM,eAAe,YACnB,OAAO,OAAwB,kBAAkB,WAAW,GAAG,EAC/D,CAAC,kBAAkB,CACpB;CAGD,MAAM,YAAY,cAAc;AAE9B,SADc,YAAY,MAAM,kBAAkB,GACnC,MAAM;IACpB,CAAC,YAAY,CAAC;CAEjB,MAAM,sBAAsB,aACzB,OAAe;AACd,WAAS,YAAY,KAAK;IAE5B,CAAC,SAAS,CACX;CAED,MAAM,aAAa,kBAAkB;AACnC,WAAS,WAAW;IACnB,CAAC,SAAS,CAAC;CAEd,MAAM,aAAa,eACV;EACL,QAAQ;EACR,MAAM,WAAW,EAAE,IAAI,SAAS,IAAI,GAAG;EACvC,YAAY;EACb,GACD,CAAC,cAAc,SAAS,CACzB;CAED,MAAM,eAAe,cACb,yCAAyC,mBAAmB,EAClE,CAAC,mBAAmB,CACrB;CACD,MAAM,mBAAmB,cACjB,6CAA6C,mBAAmB,EACtE,CAAC,mBAAmB,CACrB;CACD,MAAM,eAAe,cACb,yCAAyC,mBAAmB,EAClE,CAAC,mBAAmB,CACrB;CACD,MAAM,gBAAgB,cACd,0CAA0C,mBAAmB,EACnE,CAAC,mBAAmB,CACrB;CACD,MAAM,sBAAsB,cACpB,gDAAgD,kBAAkB,EACxE,CAAC,kBAAkB,CACpB;CAED,MAAM,WAAW,eACR;EACL,MAAM,WACF;GACE,IAAI,SAAS;GACb,SAAS,SAAS,UACd,EAAE,UAAU,SAAS,QAAQ,UAAU,GACvC;GACL,GACD,KAAA;EACJ,UAAU;EACV,WAAW,SAAiB;AAC1B,YAAS,KAAK;;EAEhB,YAAY,SAGN;AACJ,WAAQ,IAAI,cAAc,KAAK,KAAK,IAAI,KAAK,QAAQ;;EAExD,GACD,CAAC,UAAU,SAAS,CACrB;AAED,QACE,oBAAC,OAAD;EAAK,GAAI;EAAU,WAAW,UAAU,SAAS,aAAa;YAC5D,oBAAC,wBAAD;GAAwB,QAAQ;aAC9B,oBAAC,uBAAD;IACE,OAAO;IACP,WAAW;IACX,eAAe;IACf,OAAO;IACP,cAAc;cAEd,oBAAC,sBAAD;KAAsB,QAAQ;eAC5B,oBAAC,aAAD;MACE,aAAa,UAAU,SAAS;MAChC,gBAAgB,UAAU,SAAS;MACpB;MACD;MACH;MACX,iBAAiB;MACjB,QAAQ;MACR,CAAA;KACmB,CAAA;IACD,CAAA;GACD,CAAA;EACrB,CAAA;;AAIV,MAAa,+BAAqD;CAChE,YAAY;CACZ,aAAa;CACb,YAAY,CAAC;EAAE,IAAI;EAAW,OAAO;EAAW,CAAC;CACjD,QAAQ,EAAE;CACX"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ShareablesScreen-7W63bXCs.mjs","names":["portalTenantContent.dam_query","portalTenantContent.dam_assets_destroy","portalTenantContent.dam_assets_discard","portalTenantContent.dam_asset_paths_create"],"sources":["../src/hooks/use-user-type.ts","../../../file-picker/core/src/schemas/dam.ts","../../../file-picker/api-client/src/api/url-proxy.ts","../../../file-picker/api-client/src/portal-tenant-adapter.ts","../src/screens/ShareablesScreen.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport { useFluidAuth } from \"./use-fluid-auth\";\nimport { USER_TYPES, type UserType } from \"../auth/types\";\n\nexport interface UseUserTypeResult {\n userType: UserType | null;\n isCustomer: boolean;\n isRep: boolean;\n isAdmin: boolean;\n}\n\n/**\n * Convenience hook for user-type checks in the portal SDK.\n */\nexport function useUserType(): UseUserTypeResult {\n const { user } = useFluidAuth();\n\n return useMemo(() => {\n const userType = user?.user_type ?? null;\n return {\n userType,\n isCustomer: userType === USER_TYPES.customer,\n isRep: userType === USER_TYPES.rep,\n isAdmin:\n userType === USER_TYPES.admin || userType === USER_TYPES.root_admin,\n };\n }, [user?.user_type]);\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 };\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 })\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","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 { FetchClientInstance } from \"@fluid-app/api-client-core\";\nimport {\n damAssetSchema,\n damQueryResponseSchema,\n type CreateDamAssetParams,\n type CreateDamAssetPathForAssetsParams,\n type DamAssetCreateResponse,\n type DamAssetPathCreateResponse,\n type DamQueryParams,\n type DamQueryResponse,\n type FilePickerApi,\n type UnsplashSearchResponse,\n} from \"@fluid-app/file-picker-core\";\nimport {\n portalTenantContent,\n type operations,\n} from \"@fluid-app/portal-tenant-content-api-client\";\nimport { proxyUrlFetch } from \"./api/url-proxy\";\n\n/** BFF create response — derived from the generated OpenAPI types. */\ntype DamAssetCreateBffResponse = Awaited<\n ReturnType<typeof portalTenantContent.dam_assets_create>\n>;\n\n/** BFF asset path create response — derived from the generated OpenAPI types. */\ntype DamAssetPathCreateBffResponse = Awaited<\n ReturnType<typeof portalTenantContent.dam_asset_paths_create>\n>;\n\n/**\n * Maps a BFF DAM asset to the file-picker port's DamAssetCreateResponse shape.\n *\n * The BFF response includes nullable meta.request_id (from Api::Response),\n * while the port schema requires a string. We coalesce to empty string.\n */\nfunction mapCreateResponse(\n response: DamAssetCreateBffResponse,\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\n/**\n * Maps a BFF asset path response to the file-picker port's shape.\n */\nfunction mapAssetPathCreateResponse(\n response: DamAssetPathCreateBffResponse,\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\n/**\n * Creates a FilePickerApi adapter backed by the portal-tenant BFF's\n * `/api/content/dam/*` endpoints, using cookie-based auth via the\n * provided FetchClient.\n *\n * Unsplash search is not available through the BFF — callers that need\n * Unsplash should use the legacy adapter or provide their own\n * implementation.\n *\n * The `onProgress` callback in `createDamAsset` is not supported — the\n * underlying `fetch` API does not expose upload progress events.\n *\n * URL proxy delegates to the same-origin `/api/proxy-url` endpoint\n * (served by the hosting app, not the BFF) for CORS bypass, identical\n * to the legacy adapter behaviour.\n */\nexport function createPortalTenantFilePickerApiAdapter(\n client: FetchClientInstance,\n): FilePickerApi {\n return {\n createDamAsset: async (\n params: CreateDamAssetParams,\n ): Promise<DamAssetCreateResponse> => {\n // The generated dam_assets_create uses client.post (JSON body), but\n // file uploads require multipart/form-data. Use requestWithFormData\n // directly, typing the response from the generated operation type.\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 =\n await client.requestWithFormData<DamAssetCreateBffResponse>(\n \"/api/content/dam/assets\",\n formData,\n { method: \"POST\" },\n );\n\n return mapCreateResponse(response);\n },\n\n queryDamAssets: async (\n params: DamQueryParams,\n ): Promise<DamQueryResponse> => {\n const response = await portalTenantContent.dam_query(\n client,\n params satisfies operations[\"dam_query\"][\"requestBody\"][\"content\"][\"application/json\"],\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\n deleteDamAsset: async (code: string): Promise<unknown> => {\n return portalTenantContent.dam_assets_destroy(client, code);\n },\n\n discardDamAsset: async (code: string): Promise<unknown> => {\n return portalTenantContent.dam_assets_discard(client, code);\n },\n\n createDamAssetPathForAssets: async (\n params: CreateDamAssetPathForAssetsParams,\n ): Promise<DamAssetPathCreateResponse> => {\n const response = await portalTenantContent.dam_asset_paths_create(\n client,\n params.code,\n { asset_path: { path: params.asset_paths.join(\",\") } },\n );\n return mapAssetPathCreateResponse(response);\n },\n\n searchUnsplash: async (\n _query: string,\n _page?: number,\n _perPage?: number,\n ): Promise<UnsplashSearchResponse> => {\n throw new Error(\n \"Unsplash search is not available through the portal-tenant BFF. \" +\n \"Configure an Unsplash access key and use the standard FilePickerApi adapter instead.\",\n );\n },\n\n proxyUrlFetch: (url: string) => proxyUrlFetch(url),\n };\n}\n","import { useCallback, useMemo, type ComponentProps } from \"react\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"../types\";\nimport type { WidgetPropertySchema } from \"../registries/property-schema-types\";\nimport {\n ShareablesCoreProvider,\n ShareablesApiProvider,\n} from \"@fluid-app/shareables-core\";\nimport { ShareablesUIProvider, ShareablesApp } from \"@fluid-app/shareables-ui\";\nimport {\n createPortalTenantPlaylistsAdapter,\n createPortalTenantMediaShareablesAdapter,\n createPortalTenantPlaylistsShareablesAdapter,\n createPortalTenantFilesShareablesAdapter,\n createPortalTenantSharesShareablesAdapter,\n createPortalTenantProductMediaShareablesAdapter,\n} from \"@fluid-app/shareables-api-client\";\nimport { createPortalTenantFilePickerApiAdapter } from \"@fluid-app/file-picker-api-client\";\nimport { useCurrentUser } from \"../hooks/use-current-user\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\nimport { useSdkClient } from \"../account/use-account-clients\";\nimport { usePortalTenantClient } from \"../providers/PortalTenantClientProvider\";\nimport { useUserType } from \"../hooks/use-user-type\";\nimport { usePortalProductsClient } from \"../products/use-portal-products-client\";\n\ntype ShareablesScreenProps = ComponentProps<\"div\"> & {\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n};\n\n/**\n * Parse the current shareables sub-route from the full slug.\n *\n * System nav slugs are \"share/products\", \"share/media\", \"share/playlists\".\n * Detail pages append an ID: \"share/products/123\", \"share/media/456\".\n *\n * \"share/products\" → screen=\"products\", detailId=null\n * \"share/products/123\" → screen=\"products\", detailId=\"123\"\n * \"share/media/456\" → screen=\"media\", detailId=\"456\"\n * \"share/playlists\" → screen=\"playlists\", detailId=null\n * \"share/playlists/789\" → screen=\"playlists\", detailId=\"789\"\n * \"share/files\" → screen=\"files\", detailId=null\n * \"share\" → screen=null (default to products)\n */\nfunction parseShareablesRoute(currentSlug: string): {\n screen: string | null;\n detailId: string | null;\n action: string | null;\n} {\n // Strip the \"share\" prefix\n const slugWithoutPrefix = currentSlug.replace(/^share\\/?/, \"\");\n if (!slugWithoutPrefix) {\n return { screen: null, detailId: null, action: null };\n }\n\n const parts = slugWithoutPrefix.split(\"/\");\n const screen = parts[0] || null;\n const detailId = parts[1] || null;\n const action = parts[2] || null;\n return { screen, detailId, action };\n}\n\nexport function ShareablesScreen({\n /* eslint-disable @typescript-eslint/no-unused-vars -- destructured to exclude from divProps spread */\n background,\n textColor,\n accentColor,\n padding,\n borderRadius,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n ...divProps\n}: ShareablesScreenProps): React.JSX.Element {\n const domainClient = useSdkClient();\n const portalProductsApi = usePortalProductsClient();\n const portalTenantClient = usePortalTenantClient();\n const { data: userData } = useCurrentUser();\n const { currentSlug, navigate } = useAppNavigation();\n const { isCustomer } = useUserType();\n\n const fetchProducts = useCallback(\n async (search: string, cursor?: string, limit?: number) => {\n if (search) {\n return portalProductsApi.searchProducts(search, { cursor, limit });\n }\n return portalProductsApi.listProducts({ cursor, limit });\n },\n [portalProductsApi],\n );\n\n const fetchProduct = useCallback(\n async (id: string | number) => portalProductsApi.getProduct(id),\n [portalProductsApi],\n );\n\n const { screen, detailId, action } = parseShareablesRoute(currentSlug);\n\n const handleNavigate = useCallback(\n (subScreen: string, id?: string) => {\n const path = id ? `share/${subScreen}/${id}` : `share/${subScreen}`;\n navigate(path);\n },\n [navigate],\n );\n\n const handleBack = useCallback(() => {\n if (detailId && screen) {\n // Navigate back to the listing for the current screen\n navigate(`share/${screen}`);\n } else {\n // Navigate to the default shareables screen\n navigate(\"share/products\");\n }\n }, [navigate, detailId, screen]);\n\n const coreConfig = useMemo(\n () => ({\n client: domainClient,\n user: userData ? { id: userData.id } : null,\n repContext: true,\n }),\n [domainClient, userData],\n );\n\n // Create the port-level playlists adapter for the standalone deletePlaylist\n // callback (which uses the port interface directly, not ShareablesApi).\n const playlistsAdapter = useMemo(\n () => createPortalTenantPlaylistsAdapter(portalTenantClient),\n [portalTenantClient],\n );\n\n const mediaAdapter = useMemo(\n () => createPortalTenantMediaShareablesAdapter(portalTenantClient),\n [portalTenantClient],\n );\n const playlistsShareablesAdapter = useMemo(\n () => createPortalTenantPlaylistsShareablesAdapter(portalTenantClient),\n [portalTenantClient],\n );\n const filesAdapter = useMemo(\n () => createPortalTenantFilesShareablesAdapter(portalTenantClient),\n [portalTenantClient],\n );\n const sharesAdapter = useMemo(\n () => createPortalTenantSharesShareablesAdapter(portalTenantClient),\n [portalTenantClient],\n );\n const productMediaAdapter = useMemo(\n () => createPortalTenantProductMediaShareablesAdapter(portalProductsApi),\n [portalProductsApi],\n );\n\n const filePickerApi = useMemo(\n () => createPortalTenantFilePickerApiAdapter(portalTenantClient),\n [portalTenantClient],\n );\n\n const uiConfig = useMemo(\n () => ({\n user: userData\n ? {\n id: userData.id,\n company: userData.company\n ? { logo_url: userData.company.logo_url }\n : null,\n }\n : undefined,\n affiliateId:\n (userData as { affiliate_id?: number } | undefined)?.affiliate_id ??\n null,\n basePath: \"\",\n navigate: (path: string) => {\n // Strip leading slash — cards generate paths like \"/share/product/123\"\n const cleanPath = path.replace(/^\\//, \"\");\n // Ensure share/ prefix — screen components pass relative paths like \"media/new\"\n const prefixed = cleanPath.startsWith(\"share/\")\n ? cleanPath\n : `share/${cleanPath}`;\n navigate(prefixed);\n },\n showToast: (opts: {\n title: string;\n type: \"success\" | \"error\" | \"warning\";\n }) => {\n console.warn(`[Shareables] ${opts.type}: ${opts.title}`);\n },\n filePickerApi,\n onToggleFavorite: async (params: {\n favoriteableId: number;\n favoriteableType: string;\n }) => {\n const affiliateId = (userData as { affiliate_id?: number } | undefined)\n ?.affiliate_id;\n if (!affiliateId) throw new Error(\"No affiliate ID\");\n return domainClient.post<{ is_favorited: boolean }>(\n `/user_companies/${affiliateId}/favorites/toggle.json`,\n {\n favoriteable_id: params.favoriteableId,\n favoriteable_type: params.favoriteableType,\n },\n );\n },\n onDeletePlaylist: isCustomer\n ? undefined\n : async (playlistId: number) => {\n await playlistsAdapter.deletePlaylist(playlistId);\n },\n readOnly: isCustomer,\n }),\n [\n userData,\n navigate,\n filePickerApi,\n domainClient,\n isCustomer,\n playlistsAdapter,\n ],\n );\n\n return (\n <div {...divProps} className={`h-full ${divProps.className ?? \"\"}`}>\n <ShareablesCoreProvider config={coreConfig}>\n <ShareablesApiProvider\n media={mediaAdapter}\n playlists={playlistsShareablesAdapter}\n fileResources={filesAdapter}\n share={sharesAdapter}\n productMedia={productMediaAdapter}\n >\n <ShareablesUIProvider config={uiConfig}>\n <ShareablesApp\n screen={screen}\n detailId={detailId}\n action={action}\n companyLogoUrl={userData?.company?.logo_url}\n countryCode={userData?.country?.iso}\n fetchProducts={fetchProducts}\n fetchProduct={fetchProduct}\n onNavigate={handleNavigate}\n onBack={handleBack}\n />\n </ShareablesUIProvider>\n </ShareablesApiProvider>\n </ShareablesCoreProvider>\n </div>\n );\n}\n\nexport const shareablesScreenPropertySchema: WidgetPropertySchema = {\n widgetType: \"ShareablesScreen\",\n displayName: \"Shareables Screen\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ShareablesScreen-BpOu1VpJ.cjs","names":["useFluidAuth","USER_TYPES","z","z","useSdkClient","usePortalProductsClient","usePortalTenantClient","useCurrentUser","useAppNavigation","createPortalTenantPlaylistsAdapter","createPortalTenantMediaShareablesAdapter","createPortalTenantPlaylistsShareablesAdapter","createPortalTenantFilesShareablesAdapter","createPortalTenantSharesShareablesAdapter","createPortalTenantProductMediaShareablesAdapter","ShareablesCoreProvider","ShareablesApiProvider","ShareablesUIProvider","ShareablesApp"],"sources":["../src/hooks/use-user-type.ts","../../../file-picker/core/src/schemas/dam.ts","../../../file-picker/api-client/src/api/url-proxy.ts","../../../file-picker/api-client/src/portal-tenant-adapter.ts","../src/screens/ShareablesScreen.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport { useFluidAuth } from \"./use-fluid-auth\";\nimport { USER_TYPES, type UserType } from \"../auth/types\";\n\nexport interface UseUserTypeResult {\n userType: UserType | null;\n isCustomer: boolean;\n isRep: boolean;\n isAdmin: boolean;\n}\n\n/**\n * Convenience hook for user-type checks in the portal SDK.\n */\nexport function useUserType(): UseUserTypeResult {\n const { user } = useFluidAuth();\n\n return useMemo(() => {\n const userType = user?.user_type ?? null;\n return {\n userType,\n isCustomer: userType === USER_TYPES.customer,\n isRep: userType === USER_TYPES.rep,\n isAdmin:\n userType === USER_TYPES.admin || userType === USER_TYPES.root_admin,\n };\n }, [user?.user_type]);\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 };\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 })\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","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 { FetchClientInstance } from \"@fluid-app/api-client-core\";\nimport {\n damAssetSchema,\n damQueryResponseSchema,\n type CreateDamAssetParams,\n type CreateDamAssetPathForAssetsParams,\n type DamAssetCreateResponse,\n type DamAssetPathCreateResponse,\n type DamQueryParams,\n type DamQueryResponse,\n type FilePickerApi,\n type UnsplashSearchResponse,\n} from \"@fluid-app/file-picker-core\";\nimport {\n portalTenantContent,\n type operations,\n} from \"@fluid-app/portal-tenant-content-api-client\";\nimport { proxyUrlFetch } from \"./api/url-proxy\";\n\n/** BFF create response — derived from the generated OpenAPI types. */\ntype DamAssetCreateBffResponse = Awaited<\n ReturnType<typeof portalTenantContent.dam_assets_create>\n>;\n\n/** BFF asset path create response — derived from the generated OpenAPI types. */\ntype DamAssetPathCreateBffResponse = Awaited<\n ReturnType<typeof portalTenantContent.dam_asset_paths_create>\n>;\n\n/**\n * Maps a BFF DAM asset to the file-picker port's DamAssetCreateResponse shape.\n *\n * The BFF response includes nullable meta.request_id (from Api::Response),\n * while the port schema requires a string. We coalesce to empty string.\n */\nfunction mapCreateResponse(\n response: DamAssetCreateBffResponse,\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\n/**\n * Maps a BFF asset path response to the file-picker port's shape.\n */\nfunction mapAssetPathCreateResponse(\n response: DamAssetPathCreateBffResponse,\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\n/**\n * Creates a FilePickerApi adapter backed by the portal-tenant BFF's\n * `/api/content/dam/*` endpoints, using cookie-based auth via the\n * provided FetchClient.\n *\n * Unsplash search is not available through the BFF — callers that need\n * Unsplash should use the legacy adapter or provide their own\n * implementation.\n *\n * The `onProgress` callback in `createDamAsset` is not supported — the\n * underlying `fetch` API does not expose upload progress events.\n *\n * URL proxy delegates to the same-origin `/api/proxy-url` endpoint\n * (served by the hosting app, not the BFF) for CORS bypass, identical\n * to the legacy adapter behaviour.\n */\nexport function createPortalTenantFilePickerApiAdapter(\n client: FetchClientInstance,\n): FilePickerApi {\n return {\n createDamAsset: async (\n params: CreateDamAssetParams,\n ): Promise<DamAssetCreateResponse> => {\n // The generated dam_assets_create uses client.post (JSON body), but\n // file uploads require multipart/form-data. Use requestWithFormData\n // directly, typing the response from the generated operation type.\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 =\n await client.requestWithFormData<DamAssetCreateBffResponse>(\n \"/api/content/dam/assets\",\n formData,\n { method: \"POST\" },\n );\n\n return mapCreateResponse(response);\n },\n\n queryDamAssets: async (\n params: DamQueryParams,\n ): Promise<DamQueryResponse> => {\n const response = await portalTenantContent.dam_query(\n client,\n params satisfies operations[\"dam_query\"][\"requestBody\"][\"content\"][\"application/json\"],\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\n deleteDamAsset: async (code: string): Promise<unknown> => {\n return portalTenantContent.dam_assets_destroy(client, code);\n },\n\n discardDamAsset: async (code: string): Promise<unknown> => {\n return portalTenantContent.dam_assets_discard(client, code);\n },\n\n createDamAssetPathForAssets: async (\n params: CreateDamAssetPathForAssetsParams,\n ): Promise<DamAssetPathCreateResponse> => {\n const response = await portalTenantContent.dam_asset_paths_create(\n client,\n params.code,\n { asset_path: { path: params.asset_paths.join(\",\") } },\n );\n return mapAssetPathCreateResponse(response);\n },\n\n searchUnsplash: async (\n _query: string,\n _page?: number,\n _perPage?: number,\n ): Promise<UnsplashSearchResponse> => {\n throw new Error(\n \"Unsplash search is not available through the portal-tenant BFF. \" +\n \"Configure an Unsplash access key and use the standard FilePickerApi adapter instead.\",\n );\n },\n\n proxyUrlFetch: (url: string) => proxyUrlFetch(url),\n };\n}\n","import { useCallback, useMemo, type ComponentProps } from \"react\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"../types\";\nimport type { WidgetPropertySchema } from \"../registries/property-schema-types\";\nimport {\n ShareablesCoreProvider,\n ShareablesApiProvider,\n} from \"@fluid-app/shareables-core\";\nimport { ShareablesUIProvider, ShareablesApp } from \"@fluid-app/shareables-ui\";\nimport {\n createPortalTenantPlaylistsAdapter,\n createPortalTenantMediaShareablesAdapter,\n createPortalTenantPlaylistsShareablesAdapter,\n createPortalTenantFilesShareablesAdapter,\n createPortalTenantSharesShareablesAdapter,\n createPortalTenantProductMediaShareablesAdapter,\n} from \"@fluid-app/shareables-api-client\";\nimport { createPortalTenantFilePickerApiAdapter } from \"@fluid-app/file-picker-api-client\";\nimport { useCurrentUser } from \"../hooks/use-current-user\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\nimport { useSdkClient } from \"../account/use-account-clients\";\nimport { usePortalTenantClient } from \"../providers/PortalTenantClientProvider\";\nimport { useUserType } from \"../hooks/use-user-type\";\nimport { usePortalProductsClient } from \"../products/use-portal-products-client\";\n\ntype ShareablesScreenProps = ComponentProps<\"div\"> & {\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n};\n\n/**\n * Parse the current shareables sub-route from the full slug.\n *\n * System nav slugs are \"share/products\", \"share/media\", \"share/playlists\".\n * Detail pages append an ID: \"share/products/123\", \"share/media/456\".\n *\n * \"share/products\" → screen=\"products\", detailId=null\n * \"share/products/123\" → screen=\"products\", detailId=\"123\"\n * \"share/media/456\" → screen=\"media\", detailId=\"456\"\n * \"share/playlists\" → screen=\"playlists\", detailId=null\n * \"share/playlists/789\" → screen=\"playlists\", detailId=\"789\"\n * \"share/files\" → screen=\"files\", detailId=null\n * \"share\" → screen=null (default to products)\n */\nfunction parseShareablesRoute(currentSlug: string): {\n screen: string | null;\n detailId: string | null;\n action: string | null;\n} {\n // Strip the \"share\" prefix\n const slugWithoutPrefix = currentSlug.replace(/^share\\/?/, \"\");\n if (!slugWithoutPrefix) {\n return { screen: null, detailId: null, action: null };\n }\n\n const parts = slugWithoutPrefix.split(\"/\");\n const screen = parts[0] || null;\n const detailId = parts[1] || null;\n const action = parts[2] || null;\n return { screen, detailId, action };\n}\n\nexport function ShareablesScreen({\n /* eslint-disable @typescript-eslint/no-unused-vars -- destructured to exclude from divProps spread */\n background,\n textColor,\n accentColor,\n padding,\n borderRadius,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n ...divProps\n}: ShareablesScreenProps): React.JSX.Element {\n const domainClient = useSdkClient();\n const portalProductsApi = usePortalProductsClient();\n const portalTenantClient = usePortalTenantClient();\n const { data: userData } = useCurrentUser();\n const { currentSlug, navigate } = useAppNavigation();\n const { isCustomer } = useUserType();\n\n const fetchProducts = useCallback(\n async (search: string, cursor?: string, limit?: number) => {\n if (search) {\n return portalProductsApi.searchProducts(search, { cursor, limit });\n }\n return portalProductsApi.listProducts({ cursor, limit });\n },\n [portalProductsApi],\n );\n\n const fetchProduct = useCallback(\n async (id: string | number) => portalProductsApi.getProduct(id),\n [portalProductsApi],\n );\n\n const { screen, detailId, action } = parseShareablesRoute(currentSlug);\n\n const handleNavigate = useCallback(\n (subScreen: string, id?: string) => {\n const path = id ? `share/${subScreen}/${id}` : `share/${subScreen}`;\n navigate(path);\n },\n [navigate],\n );\n\n const handleBack = useCallback(() => {\n if (detailId && screen) {\n // Navigate back to the listing for the current screen\n navigate(`share/${screen}`);\n } else {\n // Navigate to the default shareables screen\n navigate(\"share/products\");\n }\n }, [navigate, detailId, screen]);\n\n const coreConfig = useMemo(\n () => ({\n client: domainClient,\n user: userData ? { id: userData.id } : null,\n repContext: true,\n }),\n [domainClient, userData],\n );\n\n // Create the port-level playlists adapter for the standalone deletePlaylist\n // callback (which uses the port interface directly, not ShareablesApi).\n const playlistsAdapter = useMemo(\n () => createPortalTenantPlaylistsAdapter(portalTenantClient),\n [portalTenantClient],\n );\n\n const mediaAdapter = useMemo(\n () => createPortalTenantMediaShareablesAdapter(portalTenantClient),\n [portalTenantClient],\n );\n const playlistsShareablesAdapter = useMemo(\n () => createPortalTenantPlaylistsShareablesAdapter(portalTenantClient),\n [portalTenantClient],\n );\n const filesAdapter = useMemo(\n () => createPortalTenantFilesShareablesAdapter(portalTenantClient),\n [portalTenantClient],\n );\n const sharesAdapter = useMemo(\n () => createPortalTenantSharesShareablesAdapter(portalTenantClient),\n [portalTenantClient],\n );\n const productMediaAdapter = useMemo(\n () => createPortalTenantProductMediaShareablesAdapter(portalProductsApi),\n [portalProductsApi],\n );\n\n const filePickerApi = useMemo(\n () => createPortalTenantFilePickerApiAdapter(portalTenantClient),\n [portalTenantClient],\n );\n\n const uiConfig = useMemo(\n () => ({\n user: userData\n ? {\n id: userData.id,\n company: userData.company\n ? { logo_url: userData.company.logo_url }\n : null,\n }\n : undefined,\n affiliateId:\n (userData as { affiliate_id?: number } | undefined)?.affiliate_id ??\n null,\n basePath: \"\",\n navigate: (path: string) => {\n // Strip leading slash — cards generate paths like \"/share/product/123\"\n const cleanPath = path.replace(/^\\//, \"\");\n // Ensure share/ prefix — screen components pass relative paths like \"media/new\"\n const prefixed = cleanPath.startsWith(\"share/\")\n ? cleanPath\n : `share/${cleanPath}`;\n navigate(prefixed);\n },\n showToast: (opts: {\n title: string;\n type: \"success\" | \"error\" | \"warning\";\n }) => {\n console.warn(`[Shareables] ${opts.type}: ${opts.title}`);\n },\n filePickerApi,\n onToggleFavorite: async (params: {\n favoriteableId: number;\n favoriteableType: string;\n }) => {\n const affiliateId = (userData as { affiliate_id?: number } | undefined)\n ?.affiliate_id;\n if (!affiliateId) throw new Error(\"No affiliate ID\");\n return domainClient.post<{ is_favorited: boolean }>(\n `/user_companies/${affiliateId}/favorites/toggle.json`,\n {\n favoriteable_id: params.favoriteableId,\n favoriteable_type: params.favoriteableType,\n },\n );\n },\n onDeletePlaylist: isCustomer\n ? undefined\n : async (playlistId: number) => {\n await playlistsAdapter.deletePlaylist(playlistId);\n },\n readOnly: isCustomer,\n }),\n [\n userData,\n navigate,\n filePickerApi,\n domainClient,\n isCustomer,\n playlistsAdapter,\n ],\n );\n\n return (\n <div {...divProps} className={`h-full ${divProps.className ?? \"\"}`}>\n <ShareablesCoreProvider config={coreConfig}>\n <ShareablesApiProvider\n media={mediaAdapter}\n playlists={playlistsShareablesAdapter}\n fileResources={filesAdapter}\n share={sharesAdapter}\n productMedia={productMediaAdapter}\n >\n <ShareablesUIProvider config={uiConfig}>\n <ShareablesApp\n screen={screen}\n detailId={detailId}\n action={action}\n companyLogoUrl={userData?.company?.logo_url}\n countryCode={userData?.country?.iso}\n fetchProducts={fetchProducts}\n fetchProduct={fetchProduct}\n onNavigate={handleNavigate}\n onBack={handleBack}\n />\n </ShareablesUIProvider>\n </ShareablesApiProvider>\n </ShareablesCoreProvider>\n </div>\n );\n}\n\nexport const shareablesScreenPropertySchema: WidgetPropertySchema = {\n widgetType: \"ShareablesScreen\",\n displayName: \"Shareables Screen\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":"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"}