@burdenoff/microfe-coolandlovely 2026.1030.1 → 2026.1031.2

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 (30) hide show
  1. package/dist/coolandlovely/CoolAndLovelyRoutes.d.ts.map +1 -1
  2. package/dist/coolandlovely/CoolAndLovelyRoutes.js +42 -38
  3. package/dist/coolandlovely/CoolAndLovelyRoutes.js.map +1 -1
  4. package/dist/coolandlovely/components/Field.d.ts +3 -1
  5. package/dist/coolandlovely/components/Field.d.ts.map +1 -1
  6. package/dist/coolandlovely/components/Field.js +5 -4
  7. package/dist/coolandlovely/components/Field.js.map +1 -1
  8. package/dist/coolandlovely/hooks/useCatalogImport.d.ts +25 -0
  9. package/dist/coolandlovely/hooks/useCatalogImport.d.ts.map +1 -0
  10. package/dist/coolandlovely/hooks/useCatalogImport.js +113 -0
  11. package/dist/coolandlovely/hooks/useCatalogImport.js.map +1 -0
  12. package/dist/coolandlovely/hooks/useCoolAndLovelyApi.d.ts +14 -2
  13. package/dist/coolandlovely/hooks/useCoolAndLovelyApi.d.ts.map +1 -1
  14. package/dist/coolandlovely/hooks/useCoolAndLovelyApi.js +14 -12
  15. package/dist/coolandlovely/hooks/useCoolAndLovelyApi.js.map +1 -1
  16. package/dist/coolandlovely/hooks/useFiles.js +6 -3
  17. package/dist/coolandlovely/hooks/useFiles.js.map +1 -1
  18. package/dist/coolandlovely/pages/brands/BrandsListPage.d.ts.map +1 -1
  19. package/dist/coolandlovely/pages/brands/BrandsListPage.js +72 -60
  20. package/dist/coolandlovely/pages/brands/BrandsListPage.js.map +1 -1
  21. package/dist/coolandlovely/pages/brands/ImportCatalogPage.d.ts +17 -0
  22. package/dist/coolandlovely/pages/brands/ImportCatalogPage.d.ts.map +1 -0
  23. package/dist/coolandlovely/pages/brands/ImportCatalogPage.js +417 -0
  24. package/dist/coolandlovely/pages/brands/ImportCatalogPage.js.map +1 -0
  25. package/dist/coolandlovely/pages/discover/DiscoverPage.d.ts.map +1 -1
  26. package/dist/coolandlovely/pages/discover/DiscoverPage.js +264 -255
  27. package/dist/coolandlovely/pages/discover/DiscoverPage.js.map +1 -1
  28. package/dist/coolandlovely/types/index.d.ts +80 -0
  29. package/dist/coolandlovely/types/index.d.ts.map +1 -1
  30. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"useCoolAndLovelyApi.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/hooks/useCoolAndLovelyApi.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useCoolAndLovelyApi.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/hooks/useCoolAndLovelyApi.ts"],"names":[],"mappings":"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"}
@@ -786,47 +786,49 @@ var o = "coolandlovely", s = async (e, t, n) => {
786
786
  n.invalidateQueries({ queryKey: [o, "lookbooks"] }), n.invalidateQueries({ queryKey: [o, "lookbook"] });
787
787
  }
788
788
  });
789
- }, ve = (t) => {
790
- let { apiGatewayUrl: r } = e();
789
+ }, ve = ({ enabled: t = !0, ...r }) => {
790
+ let { apiGatewayUrl: i } = e();
791
791
  return n({
792
792
  queryKey: [
793
793
  o,
794
794
  "search-style-items",
795
- t
795
+ r
796
796
  ],
797
+ enabled: t,
797
798
  queryFn: async () => (await s(`query CooSearchStyleItems($input: CooSearchStyleItemsInput!, $pagination: PaginationInput) {
798
799
  cooSearchStyleItems(input: $input, pagination: $pagination) {
799
800
  items { ${u} brand { id name handle } }
800
801
  pageInfo { cursor hasMore }
801
802
  }
802
803
  }`, {
803
- input: t.input,
804
- pagination: t.pagination ?? {
804
+ input: r.input,
805
+ pagination: r.pagination ?? {
805
806
  limit: 24,
806
807
  offset: 0
807
808
  }
808
- }, r)).cooSearchStyleItems
809
+ }, i)).cooSearchStyleItems
809
810
  });
810
- }, ye = (t) => {
811
- let { apiGatewayUrl: r } = e();
811
+ }, ye = ({ enabled: t = !0, ...r }) => {
812
+ let { apiGatewayUrl: i } = e();
812
813
  return n({
813
814
  queryKey: [
814
815
  o,
815
816
  "search-looks",
816
- t
817
+ r
817
818
  ],
819
+ enabled: t,
818
820
  queryFn: async () => (await s(`query CooSearchLooks($input: CooSearchLooksInput!, $pagination: PaginationInput) {
819
821
  cooSearchLooks(input: $input, pagination: $pagination) {
820
822
  items { ${f} }
821
823
  pageInfo { cursor hasMore }
822
824
  }
823
825
  }`, {
824
- input: t.input,
825
- pagination: t.pagination ?? {
826
+ input: r.input,
827
+ pagination: r.pagination ?? {
826
828
  limit: 24,
827
829
  offset: 0
828
830
  }
829
- }, r)).cooSearchLooks
831
+ }, i)).cooSearchLooks
830
832
  });
831
833
  }, be = () => {
832
834
  let n = r(), { apiGatewayUrl: i } = e();
@@ -1 +1 @@
1
- {"version":3,"file":"useCoolAndLovelyApi.js","names":[],"sources":["../../../src/coolandlovely/hooks/useCoolAndLovelyApi.ts"],"sourcesContent":["/**\n * CoolAndLovely API hooks\n * @module coolandlovely/hooks\n *\n * Thin, strictly-typed React Query layer over the federated\n * `wspace-coolandlovely-svc` GraphQL contract. Every query/mutation here maps\n * 1:1 to a real `coo*` root field — no mocks. Requests go through the workspace\n * gateway via `graphqlFetch({ gateway: 'workspace', workspaceToken: true })`.\n */\n\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\n\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\n// Imported from the `/fetch` subpath (not the barrel) so it resolves against the\n// MFE's pinned fe-libs, which exposes the helper in fetch but not yet in the\n// graphql barrel index.\nimport { clearGraphqlFetchResponseCache } from '@burdenoff/fe-libs/shared/graphql/fetch';\n\nimport { useCoolAndLovely } from '../context';\nimport type {\n CooAddLookbookEntryInput,\n CooBrand,\n CooBrandConnection,\n CooBrandStatus,\n CooCollaboration,\n CooCollaborationConnection,\n CooCollaborationStatus,\n CooCollection,\n CooCollectionConnection,\n CooCollectionStatus,\n CooCreateBrandInput,\n CooCreateCollaborationInput,\n CooCreateCollectionInput,\n CooCreateLookInput,\n CooCreateLookbookInput,\n CooCreateStyleItemInput,\n CooCreateWardrobeItemInput,\n CooLook,\n CooLookConnection,\n CooLookItemConnection,\n CooLookOccasion,\n CooLookbook,\n CooLookbookEntryConnection,\n CooStyleCategory,\n CooStyleItem,\n CooStyleItemConnection,\n CooStyleItemStatus,\n CooStyleProfile,\n CooStyleProfileConnection,\n CooUpdateBrandInput,\n CooUpdateCollaborationInput,\n CooUpdateCollectionInput,\n CooUpdateLookInput,\n CooUpdateStyleItemInput,\n CooUpdateWardrobeItemInput,\n CooUpsertStyleProfileInput,\n CooWardrobeItem,\n CooWardrobeItemConnection,\n CooWardrobeSource,\n PaginationInput,\n CooSearchStyleItemsInput,\n CooSearchLooksInput,\n CooReviewCollaborationInput,\n} from '../types';\n\n// ---------------------------------------------------------------------------\n// Query key root\n// ---------------------------------------------------------------------------\n\nconst QK = 'coolandlovely';\n\n// ---------------------------------------------------------------------------\n// Low-level fetch wrapper\n// ---------------------------------------------------------------------------\n\nexport const coolQuery = async <TData>(\n query: string,\n variables: Record<string, unknown>,\n baseUrl?: string\n): Promise<TData> => {\n const response = await graphqlFetch<TData>({\n gateway: 'workspace',\n baseUrl,\n query,\n variables,\n workspaceToken: true,\n });\n\n if (response.errors?.length) {\n throw new Error(response.errors[0]?.message ?? 'GraphQL request failed');\n }\n if (!response.data) {\n throw new Error('GraphQL response did not include data');\n }\n // fe-libs graphqlFetch caches every *query* response for ~15s in a global\n // response cache. After a successful mutation we drop that cache so the\n // React Query `invalidateQueries` refetch reads fresh data instead of the\n // stale pre-mutation response (otherwise a like/publish/transition/remove\n // shows no change for up to 15s).\n if (/^\\s*mutation\\b/.test(query)) {\n clearGraphqlFetchResponseCache();\n }\n return response.data;\n};\n\n// ---------------------------------------------------------------------------\n// Reusable GraphQL field selections\n// ---------------------------------------------------------------------------\n\nconst BRAND_FIELDS = `\n id workspaceId name handle tagline bio aesthetics tags websiteUrl\n isFeatured status logo { id } cover { id } createdAt updatedAt\n`;\n\nconst COLLECTION_FIELDS = `\n id workspaceId brandId name description season status tags\n cover { id } publishAt endAt createdAt updatedAt\n`;\n\nconst STYLE_ITEM_FIELDS = `\n id workspaceId brandId collectionId name description category status\n sku price currency colours sizes materials tags image { id }\n createdAt updatedAt\n`;\n\n/** The piece's Burdenoff store catalogue listing state (BOFF-3430). */\nconst STORE_LISTING_FIELDS = `\n storeProductId storeListingStatus storeSyncStatus storeSyncedAt\n`;\n\nconst LOOK_FIELDS = `\n id workspaceId authorId title caption occasion visibility isFeatured\n likeCount saveCount collaborationId image { id } tags publishedAt\n createdAt updatedAt isLikedByMe isSavedByMe\n`;\n\nconst LOOK_ITEM_FIELDS = `\n id workspaceId lookId styleItemId position styling createdAt updatedAt\n styleItem { id name category price currency brand { id name handle } image { id } }\n`;\n\nconst COLLABORATION_FIELDS = `\n id workspaceId brandId creatorId collectionId title brief role status\n compensation currency tags startDate endDate publishedAt createdAt updatedAt\n`;\n\n/** Fields of a collaboration fee (BOFF-9637), shared with the commerce hooks. */\nexport const COLLABORATION_PAYOUT_FIELDS = `\n id collaborationId collaborationTitle brandId creatorId amount currency status paymentProvider\n paidAt earningAvailableAt earningSyncStatus createdAt updatedAt\n`;\n\nconst WARDROBE_FIELDS = `\n id workspaceId profileId name category source brandName colour size notes\n styleItemId purchasePrice currency costPerWear timesWorn lastWornAt tags\n image { id } createdAt updatedAt\n`;\n\nconst PROFILE_FIELDS = `\n id workspaceId ownerId displayName bio visibility stylePreferences\n palette favouriteBrands sizes createdAt updatedAt\n isFollowedByMe followerCount followingCount\n`;\n\nconst LOOKBOOK_FIELDS = `\n id workspaceId ownerId profileId name description visibility tags\n cover { id } createdAt updatedAt\n`;\n\n// ===========================================================================\n// Brands\n// ===========================================================================\n\nexport interface ListBrandsArgs {\n status?: CooBrandStatus;\n featured?: boolean;\n pagination?: PaginationInput;\n}\n\nexport const useBrands = (args: ListBrandsArgs = {}) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'brands', args],\n queryFn: async () => {\n const data = await coolQuery<{ cooListBrands: CooBrandConnection }>(\n `query CooListBrands($status: CooBrandStatus, $featured: Boolean, $pagination: PaginationInput) {\n cooListBrands(status: $status, featured: $featured, pagination: $pagination) {\n items { ${BRAND_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n status: args.status,\n featured: args.featured,\n pagination: args.pagination ?? { limit: 50, offset: 0 },\n },\n apiGatewayUrl\n );\n return data.cooListBrands;\n },\n });\n};\n\n/** Wire shape of `cooBrand` — its nested `collections`/`items` are Connections, flattened below. */\ntype CooBrandWire = Omit<CooBrand, 'collections' | 'items'> & {\n collections?: CooCollectionConnection | null;\n items?: CooStyleItemConnection | null;\n};\n\nexport const useBrand = (id: string | undefined) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'brand', id],\n queryFn: async () => {\n const data = await coolQuery<{ cooBrand: CooBrandWire | null }>(\n `query CooBrand($id: ID!) {\n cooBrand(id: $id) {\n ${BRAND_FIELDS}\n collections { items { ${COLLECTION_FIELDS} } pageInfo { cursor hasMore } }\n items { items { ${STYLE_ITEM_FIELDS} } pageInfo { cursor hasMore } }\n }\n }`,\n { id },\n apiGatewayUrl\n );\n if (!data.cooBrand) return null;\n const { collections, items, ...rest } = data.cooBrand;\n return {\n ...rest,\n collections: collections?.items ?? [],\n items: items?.items ?? [],\n } as CooBrand;\n },\n enabled: Boolean(id),\n });\n};\n\nexport const useCreateBrand = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (input: CooCreateBrandInput) => {\n const data = await coolQuery<{ cooCreateBrand: CooBrand }>(\n `mutation CooCreateBrand($input: CooCreateBrandInput!) {\n cooCreateBrand(input: $input) { ${BRAND_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooCreateBrand;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'brands'] });\n },\n });\n};\n\nexport const useUpdateBrand = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async ({ id, input }: { id: string; input: CooUpdateBrandInput }) => {\n const data = await coolQuery<{ cooUpdateBrand: CooBrand }>(\n `mutation CooUpdateBrand($id: ID!, $input: CooUpdateBrandInput!) {\n cooUpdateBrand(id: $id, input: $input) { ${BRAND_FIELDS} }\n }`,\n { id, input },\n apiGatewayUrl\n );\n return data.cooUpdateBrand;\n },\n onSuccess: (brand) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'brands'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'brand', brand.id] });\n },\n });\n};\n\nexport const useTransitionBrand = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async ({ id, status }: { id: string; status: CooBrandStatus }) => {\n const data = await coolQuery<{ cooTransitionBrand: CooBrand }>(\n `mutation CooTransitionBrand($id: ID!, $status: CooBrandStatus!) {\n cooTransitionBrand(id: $id, status: $status) { ${BRAND_FIELDS} }\n }`,\n { id, status },\n apiGatewayUrl\n );\n return data.cooTransitionBrand;\n },\n onSuccess: (brand) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'brands'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'brand', brand.id] });\n },\n });\n};\n\nexport const useArchiveBrand = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooArchiveBrand: boolean }>(\n `mutation CooArchiveBrand($id: ID!) { cooArchiveBrand(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return data.cooArchiveBrand;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'brands'] });\n },\n });\n};\n\n// ===========================================================================\n// Collections\n// ===========================================================================\n\nexport interface ListCollectionsArgs {\n brandId?: string;\n status?: CooCollectionStatus;\n}\n\nexport const useCollections = (args: ListCollectionsArgs = {}) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'collections', args],\n queryFn: async () => {\n const data = await coolQuery<{ cooListCollections: CooCollectionConnection }>(\n `query CooListCollections($brandId: ID, $status: CooCollectionStatus) {\n cooListCollections(brandId: $brandId, status: $status) {\n items { ${COLLECTION_FIELDS} brand { id name handle } }\n pageInfo { cursor hasMore }\n }\n }`,\n { brandId: args.brandId, status: args.status },\n apiGatewayUrl\n );\n return data.cooListCollections.items;\n },\n });\n};\n\n/** Wire shape of `cooCollection` — its nested `items` is a Connection, flattened below. */\ntype CooCollectionWire = Omit<CooCollection, 'items'> & { items?: CooStyleItemConnection | null };\n\nexport const useCollection = (id: string | undefined) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'collection', id],\n queryFn: async () => {\n const data = await coolQuery<{ cooCollection: CooCollectionWire | null }>(\n `query CooCollection($id: ID!) {\n cooCollection(id: $id) {\n ${COLLECTION_FIELDS}\n brand { id name handle }\n items { items { ${STYLE_ITEM_FIELDS} } pageInfo { cursor hasMore } }\n }\n }`,\n { id },\n apiGatewayUrl\n );\n if (!data.cooCollection) return null;\n const { items, ...rest } = data.cooCollection;\n return { ...rest, items: items?.items ?? [] } as CooCollection;\n },\n enabled: Boolean(id),\n });\n};\n\nexport const useCreateCollection = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (input: CooCreateCollectionInput) => {\n const data = await coolQuery<{ cooCreateCollection: CooCollection }>(\n `mutation CooCreateCollection($input: CooCreateCollectionInput!) {\n cooCreateCollection(input: $input) { ${COLLECTION_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooCreateCollection;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'collections'] });\n },\n });\n};\n\nexport const useUpdateCollection = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async ({ id, input }: { id: string; input: CooUpdateCollectionInput }) => {\n const data = await coolQuery<{ cooUpdateCollection: CooCollection }>(\n `mutation CooUpdateCollection($id: ID!, $input: CooUpdateCollectionInput!) {\n cooUpdateCollection(id: $id, input: $input) { ${COLLECTION_FIELDS} }\n }`,\n { id, input },\n apiGatewayUrl\n );\n return data.cooUpdateCollection;\n },\n onSuccess: (collection) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'collections'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'collection', collection.id] });\n },\n });\n};\n\nexport const usePublishCollection = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooPublishCollection: CooCollection }>(\n `mutation CooPublishCollection($id: ID!) {\n cooPublishCollection(id: $id) { ${COLLECTION_FIELDS} }\n }`,\n { id },\n apiGatewayUrl\n );\n return data.cooPublishCollection;\n },\n onSuccess: (collection) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'collections'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'collection', collection.id] });\n },\n });\n};\n\nexport const useArchiveCollection = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooArchiveCollection: boolean }>(\n `mutation CooArchiveCollection($id: ID!) { cooArchiveCollection(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return data.cooArchiveCollection;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'collections'] });\n },\n });\n};\n\n// ===========================================================================\n// Style Items\n// ===========================================================================\n\nexport interface ListStyleItemsArgs {\n brandId?: string;\n collectionId?: string;\n category?: CooStyleCategory;\n status?: CooStyleItemStatus;\n pagination?: PaginationInput;\n}\n\nexport const useStyleItems = (args: ListStyleItemsArgs = {}) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'style-items', args],\n queryFn: async () => {\n const data = await coolQuery<{ cooListStyleItems: CooStyleItemConnection }>(\n `query CooListStyleItems(\n $brandId: ID, $collectionId: ID, $category: CooStyleCategory,\n $status: CooStyleItemStatus, $pagination: PaginationInput\n ) {\n cooListStyleItems(\n brandId: $brandId, collectionId: $collectionId, category: $category,\n status: $status, pagination: $pagination\n ) {\n items { ${STYLE_ITEM_FIELDS} brand { id name handle } }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n brandId: args.brandId,\n collectionId: args.collectionId,\n category: args.category,\n status: args.status,\n pagination: args.pagination ?? { limit: 50, offset: 0 },\n },\n apiGatewayUrl\n );\n return data.cooListStyleItems;\n },\n });\n};\n\nexport const useStyleItem = (id: string | undefined) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'style-item', id],\n queryFn: async () => {\n const data = await coolQuery<{ cooStyleItem: CooStyleItem | null }>(\n `query CooStyleItem($id: ID!) {\n cooStyleItem(id: $id) {\n ${STYLE_ITEM_FIELDS}\n ${STORE_LISTING_FIELDS}\n brand { id name handle }\n collection { id name }\n }\n }`,\n { id },\n apiGatewayUrl\n );\n return data.cooStyleItem;\n },\n enabled: Boolean(id),\n });\n};\n\nexport const useCreateStyleItem = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (input: CooCreateStyleItemInput) => {\n const data = await coolQuery<{ cooCreateStyleItem: CooStyleItem }>(\n `mutation CooCreateStyleItem($input: CooCreateStyleItemInput!) {\n cooCreateStyleItem(input: $input) { ${STYLE_ITEM_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooCreateStyleItem;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'style-items'] });\n },\n });\n};\n\nexport const useUpdateStyleItem = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async ({ id, input }: { id: string; input: CooUpdateStyleItemInput }) => {\n const data = await coolQuery<{ cooUpdateStyleItem: CooStyleItem }>(\n `mutation CooUpdateStyleItem($id: ID!, $input: CooUpdateStyleItemInput!) {\n cooUpdateStyleItem(id: $id, input: $input) { ${STYLE_ITEM_FIELDS} }\n }`,\n { id, input },\n apiGatewayUrl\n );\n return data.cooUpdateStyleItem;\n },\n onSuccess: (item) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'style-items'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'style-item', item.id] });\n // Sizes or colours may have changed, and with them the variants that hold stock.\n void queryClient.invalidateQueries({ queryKey: [QK, 'style-item-inventory', item.id] });\n },\n });\n};\n\n/**\n * Re-drive the push of a piece to its Burdenoff store catalogue listing\n * (`cooSyncStyleItemStoreListing`, BOFF-3430). Listings normally follow every\n * change automatically; this is the manual retry for a FAILED sync. The\n * service records a failed push on the piece rather than throwing, so the\n * returned item carries the new outcome either way.\n */\nexport const useSyncStyleItemStoreListing = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooSyncStyleItemStoreListing: CooStyleItem }>(\n `mutation CooSyncStyleItemStoreListing($id: ID!) {\n cooSyncStyleItemStoreListing(id: $id) { id ${STORE_LISTING_FIELDS} }\n }`,\n { id },\n apiGatewayUrl\n );\n return data.cooSyncStyleItemStoreListing;\n },\n onSuccess: (synced) => {\n queryClient.setQueryData<CooStyleItem | null>([QK, 'style-item', synced.id], (prev) =>\n prev ? { ...prev, ...synced } : prev\n );\n void queryClient.invalidateQueries({ queryKey: [QK, 'style-item', synced.id] });\n },\n });\n};\n\nexport const useArchiveStyleItem = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooArchiveStyleItem: boolean }>(\n `mutation CooArchiveStyleItem($id: ID!) { cooArchiveStyleItem(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return data.cooArchiveStyleItem;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'style-items'] });\n },\n });\n};\n\n// ===========================================================================\n// Looks\n// ===========================================================================\n\nexport interface ListLooksArgs {\n authorId?: string;\n occasion?: CooLookOccasion;\n featured?: boolean;\n pagination?: PaginationInput;\n}\n\nexport const useLooks = (args: ListLooksArgs = {}) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'looks', args],\n queryFn: async () => {\n const data = await coolQuery<{ cooListLooks: CooLookConnection }>(\n `query CooListLooks(\n $authorId: ID, $occasion: CooLookOccasion, $featured: Boolean, $pagination: PaginationInput\n ) {\n cooListLooks(authorId: $authorId, occasion: $occasion, featured: $featured, pagination: $pagination) {\n items { ${LOOK_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n authorId: args.authorId,\n occasion: args.occasion,\n featured: args.featured,\n pagination: args.pagination ?? { limit: 50, offset: 0 },\n },\n apiGatewayUrl\n );\n return data.cooListLooks;\n },\n });\n};\n\n/** Wire shape of `cooLook` — its nested `items` is a Connection, flattened below. */\ntype CooLookWire = Omit<CooLook, 'items'> & { items?: CooLookItemConnection | null };\n\nexport const useLook = (id: string | undefined) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'look', id],\n queryFn: async () => {\n const data = await coolQuery<{ cooLook: CooLookWire | null }>(\n `query CooLook($id: ID!) {\n cooLook(id: $id) {\n ${LOOK_FIELDS}\n items { items { ${LOOK_ITEM_FIELDS} } pageInfo { cursor hasMore } }\n }\n }`,\n { id },\n apiGatewayUrl\n );\n if (!data.cooLook) return null;\n const { items, ...rest } = data.cooLook;\n return { ...rest, items: items?.items ?? [] } as CooLook;\n },\n enabled: Boolean(id),\n });\n};\n\nexport const useLooksWithItems = (args: ListLooksArgs = {}) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'looks-with-items', args],\n queryFn: async () => {\n const data = await coolQuery<{\n cooListLooks: { items: CooLookWire[]; pageInfo: CooLookConnection['pageInfo'] };\n }>(\n `query CooListLooksWithItems(\n $authorId: ID, $occasion: CooLookOccasion, $featured: Boolean, $pagination: PaginationInput\n ) {\n cooListLooks(authorId: $authorId, occasion: $occasion, featured: $featured, pagination: $pagination) {\n items { ${LOOK_FIELDS} items { items { ${LOOK_ITEM_FIELDS} } pageInfo { cursor hasMore } } }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n authorId: args.authorId,\n occasion: args.occasion,\n featured: args.featured,\n pagination: args.pagination ?? { limit: 50, offset: 0 },\n },\n apiGatewayUrl\n );\n return {\n items: data.cooListLooks.items.map(\n ({ items, ...rest }) => ({ ...rest, items: items?.items ?? [] }) as CooLook\n ),\n pageInfo: data.cooListLooks.pageInfo,\n };\n },\n });\n};\n\nexport const useCreateLook = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (input: CooCreateLookInput) => {\n const data = await coolQuery<{ cooCreateLook: CooLook }>(\n `mutation CooCreateLook($input: CooCreateLookInput!) {\n cooCreateLook(input: $input) { ${LOOK_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooCreateLook;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks-with-items'] });\n },\n });\n};\n\nexport const useUpdateLook = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async ({ id, input }: { id: string; input: CooUpdateLookInput }) => {\n const data = await coolQuery<{ cooUpdateLook: CooLook }>(\n `mutation CooUpdateLook($id: ID!, $input: CooUpdateLookInput!) {\n cooUpdateLook(id: $id, input: $input) { ${LOOK_FIELDS} }\n }`,\n { id, input },\n apiGatewayUrl\n );\n return data.cooUpdateLook;\n },\n onSuccess: (look) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks-with-items'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'look', look.id] });\n },\n });\n};\n\nexport const usePublishLook = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooPublishLook: CooLook }>(\n `mutation CooPublishLook($id: ID!) { cooPublishLook(id: $id) { ${LOOK_FIELDS} } }`,\n { id },\n apiGatewayUrl\n );\n return data.cooPublishLook;\n },\n onSuccess: (look) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks-with-items'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'look', look.id] });\n },\n });\n};\n\nexport const useLikeLook = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooLikeLook: CooLook }>(\n `mutation CooLikeLook($id: ID!) { cooLikeLook(id: $id) { ${LOOK_FIELDS} } }`,\n { id },\n apiGatewayUrl\n );\n return data.cooLikeLook;\n },\n onSuccess: (look) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks-with-items'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'look', look.id] });\n },\n });\n};\n\nexport const useUnlikeLook = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooUnlikeLook: CooLook }>(\n `mutation CooUnlikeLook($id: ID!) { cooUnlikeLook(id: $id) { ${LOOK_FIELDS} } }`,\n { id },\n apiGatewayUrl\n );\n return data.cooUnlikeLook;\n },\n onSuccess: (look) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks-with-items'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'look', look.id] });\n },\n });\n};\n\nexport const useSaveLook = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooSaveLook: CooLook }>(\n `mutation CooSaveLook($id: ID!) { cooSaveLook(id: $id) { ${LOOK_FIELDS} } }`,\n { id },\n apiGatewayUrl\n );\n return data.cooSaveLook;\n },\n onSuccess: (look) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks-with-items'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'look', look.id] });\n },\n });\n};\n\nexport const useUnsaveLook = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooUnsaveLook: CooLook }>(\n `mutation CooUnsaveLook($id: ID!) { cooUnsaveLook(id: $id) { ${LOOK_FIELDS} } }`,\n { id },\n apiGatewayUrl\n );\n return data.cooUnsaveLook;\n },\n onSuccess: (look) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks-with-items'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'look', look.id] });\n },\n });\n};\n\nexport const useDeleteLook = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooDeleteLook: boolean }>(\n `mutation CooDeleteLook($id: ID!) { cooDeleteLook(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return data.cooDeleteLook;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks-with-items'] });\n },\n });\n};\n\n// ===========================================================================\n// Collaborations\n// ===========================================================================\n\nexport interface ListCollaborationsArgs {\n brandId?: string;\n creatorId?: string;\n status?: CooCollaborationStatus;\n}\n\nexport const useCollaborations = (args: ListCollaborationsArgs = {}) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'collaborations', args],\n queryFn: async () => {\n const data = await coolQuery<{ cooListCollaborations: CooCollaborationConnection }>(\n `query CooListCollaborations($brandId: ID, $creatorId: ID, $status: CooCollaborationStatus) {\n cooListCollaborations(brandId: $brandId, creatorId: $creatorId, status: $status) {\n items { ${COLLABORATION_FIELDS} brand { id name handle logo { id } } }\n pageInfo { cursor hasMore }\n }\n }`,\n { brandId: args.brandId, creatorId: args.creatorId, status: args.status },\n apiGatewayUrl\n );\n return data.cooListCollaborations.items;\n },\n });\n};\n\n/** Wire shape of `cooCollaboration` — its nested `looks` is a Connection, flattened below. */\ntype CooCollaborationWire = Omit<CooCollaboration, 'looks'> & { looks?: CooLookConnection | null };\n\nexport const useCollaboration = (id: string | undefined) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'collaboration', id],\n queryFn: async () => {\n const data = await coolQuery<{ cooCollaboration: CooCollaborationWire | null }>(\n `query CooCollaboration($id: ID!) {\n cooCollaboration(id: $id) {\n ${COLLABORATION_FIELDS}\n brand { id name handle logo { id } }\n looks { items { ${LOOK_FIELDS} } pageInfo { cursor hasMore } }\n payout { ${COLLABORATION_PAYOUT_FIELDS} }\n }\n }`,\n { id },\n apiGatewayUrl\n );\n if (!data.cooCollaboration) return null;\n const { looks, ...rest } = data.cooCollaboration;\n return { ...rest, looks: looks?.items ?? [] } as CooCollaboration;\n },\n enabled: Boolean(id),\n });\n};\n\nexport const useCreateCollaboration = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (input: CooCreateCollaborationInput) => {\n const data = await coolQuery<{ cooCreateCollaboration: CooCollaboration }>(\n `mutation CooCreateCollaboration($input: CooCreateCollaborationInput!) {\n cooCreateCollaboration(input: $input) { ${COLLABORATION_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooCreateCollaboration;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'collaborations'] });\n },\n });\n};\n\nexport const useUpdateCollaboration = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async ({ id, input }: { id: string; input: CooUpdateCollaborationInput }) => {\n const data = await coolQuery<{ cooUpdateCollaboration: CooCollaboration }>(\n `mutation CooUpdateCollaboration($id: ID!, $input: CooUpdateCollaborationInput!) {\n cooUpdateCollaboration(id: $id, input: $input) {\n ${COLLABORATION_FIELDS}\n brand { id name handle logo { id } }\n }\n }`,\n { id, input },\n apiGatewayUrl\n );\n return data.cooUpdateCollaboration;\n },\n onSuccess: (collab) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'collaborations'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'collaboration', collab.id] });\n },\n });\n};\n\nexport const useTransitionCollaboration = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async ({ id, status }: { id: string; status: CooCollaborationStatus }) => {\n const data = await coolQuery<{ cooTransitionCollaboration: CooCollaboration }>(\n `mutation CooTransitionCollaboration($id: ID!, $status: CooCollaborationStatus!) {\n cooTransitionCollaboration(id: $id, status: $status) { ${COLLABORATION_FIELDS} }\n }`,\n { id, status },\n apiGatewayUrl\n );\n return data.cooTransitionCollaboration;\n },\n onSuccess: (collab) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'collaborations'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'collaboration', collab.id] });\n },\n });\n};\n\n/** Delete a still-PROPOSED collaboration (the svc rejects this once it has moved past PROPOSED). */\nexport const useDeleteCollaboration = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooDeleteCollaboration: boolean }>(\n `mutation CooDeleteCollaboration($id: ID!) { cooDeleteCollaboration(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return data.cooDeleteCollaboration;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'collaborations'] });\n },\n });\n};\n\n// ===========================================================================\n// Wardrobe (self-scoped)\n// ===========================================================================\n\nexport interface ListWardrobeArgs {\n category?: CooStyleCategory;\n source?: CooWardrobeSource;\n}\n\nexport const useWardrobeItems = (args: ListWardrobeArgs = {}) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'wardrobe', args],\n queryFn: async () => {\n const data = await coolQuery<{ cooListWardrobeItems: CooWardrobeItemConnection }>(\n `query CooListWardrobeItems($category: CooStyleCategory, $source: CooWardrobeSource) {\n cooListWardrobeItems(category: $category, source: $source) {\n items { ${WARDROBE_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n { category: args.category, source: args.source },\n apiGatewayUrl\n );\n return data.cooListWardrobeItems.items;\n },\n });\n};\n\nexport const useCreateWardrobeItem = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (input: CooCreateWardrobeItemInput) => {\n const data = await coolQuery<{ cooCreateWardrobeItem: CooWardrobeItem }>(\n `mutation CooCreateWardrobeItem($input: CooCreateWardrobeItemInput!) {\n cooCreateWardrobeItem(input: $input) { ${WARDROBE_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooCreateWardrobeItem;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'wardrobe'] });\n },\n });\n};\n\nexport const useUpdateWardrobeItem = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async ({ id, input }: { id: string; input: CooUpdateWardrobeItemInput }) => {\n const data = await coolQuery<{ cooUpdateWardrobeItem: CooWardrobeItem }>(\n `mutation CooUpdateWardrobeItem($id: ID!, $input: CooUpdateWardrobeItemInput!) {\n cooUpdateWardrobeItem(id: $id, input: $input) { ${WARDROBE_FIELDS} }\n }`,\n { id, input },\n apiGatewayUrl\n );\n return data.cooUpdateWardrobeItem;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'wardrobe'] });\n },\n });\n};\n\nexport const useLogWardrobeWear = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooLogWardrobeWear: CooWardrobeItem }>(\n `mutation CooLogWardrobeWear($id: ID!) {\n cooLogWardrobeWear(id: $id) { ${WARDROBE_FIELDS} }\n }`,\n { id },\n apiGatewayUrl\n );\n return data.cooLogWardrobeWear;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'wardrobe'] });\n },\n });\n};\n\nexport const useRemoveWardrobeItem = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooRemoveWardrobeItem: boolean }>(\n `mutation CooRemoveWardrobeItem($id: ID!) { cooRemoveWardrobeItem(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return data.cooRemoveWardrobeItem;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'wardrobe'] });\n },\n });\n};\n\n// ===========================================================================\n// Style Profile (self-scoped)\n// ===========================================================================\n\nexport const useMyStyleProfile = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'my-style-profile'],\n queryFn: async () => {\n const data = await coolQuery<{ cooMyStyleProfile: CooStyleProfile | null }>(\n `query CooMyStyleProfile { cooMyStyleProfile { ${PROFILE_FIELDS} } }`,\n {},\n apiGatewayUrl\n );\n return data.cooMyStyleProfile;\n },\n });\n};\n\n/**\n * A style profile by its own id, honoring CooVisibility (PRIVATE/FOLLOWERS\n * gated server-side). Returns null when not found or not visible to the\n * caller. Disabled until `id` is provided.\n */\nexport const useStyleProfile = (id: string | undefined) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'style-profile', id],\n queryFn: async () => {\n const data = await coolQuery<{ cooStyleProfile: CooStyleProfile | null }>(\n `query CooStyleProfile($id: ID!) { cooStyleProfile(id: $id) { ${PROFILE_FIELDS} } }`,\n { id },\n apiGatewayUrl\n );\n return data.cooStyleProfile;\n },\n enabled: Boolean(id),\n });\n};\n\n/**\n * Same visibility gate as `useStyleProfile`, looked up by the profile\n * owner's actor id — powers `/profile/:userId` (the public profile route\n * reached from an author's name/avatar on a Look/Discover/Collaboration\n * card). Disabled until `ownerId` is provided.\n */\nexport const useStyleProfileByOwner = (ownerId: string | undefined) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'style-profile-by-owner', ownerId],\n queryFn: async () => {\n const data = await coolQuery<{ cooStyleProfileByOwner: CooStyleProfile | null }>(\n `query CooStyleProfileByOwner($ownerId: ID!) {\n cooStyleProfileByOwner(ownerId: $ownerId) { ${PROFILE_FIELDS} }\n }`,\n { ownerId },\n apiGatewayUrl\n );\n return data.cooStyleProfileByOwner;\n },\n enabled: Boolean(ownerId),\n });\n};\n\nexport const useUpsertStyleProfile = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (input: CooUpsertStyleProfileInput) => {\n const data = await coolQuery<{ cooUpsertStyleProfile: CooStyleProfile }>(\n `mutation CooUpsertStyleProfile($input: CooUpsertStyleProfileInput!) {\n cooUpsertStyleProfile(input: $input) { ${PROFILE_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooUpsertStyleProfile;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'my-style-profile'] });\n },\n });\n};\n\n// ===========================================================================\n// Lookbooks\n// ===========================================================================\n\n/** The plain `CooLookbookEntry` field selection reused across lookbook queries. */\nconst LOOKBOOK_ENTRY_FIELDS =\n 'id workspaceId lookbookId lookId styleItemId note position createdAt updatedAt';\n\nexport const useLookbooks = (ownerId?: string) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'lookbooks', ownerId],\n queryFn: async () => {\n const data = await coolQuery<{\n cooListLookbooks: {\n items: (CooLookbook & { entries?: CooLookbookEntryConnection | null })[];\n pageInfo: unknown;\n };\n }>(\n `query CooListLookbooks($ownerId: ID) {\n cooListLookbooks(ownerId: $ownerId) {\n items {\n ${LOOKBOOK_FIELDS}\n entries { items { ${LOOKBOOK_ENTRY_FIELDS} } pageInfo { cursor hasMore } }\n }\n pageInfo { cursor hasMore }\n }\n }`,\n { ownerId },\n apiGatewayUrl\n );\n return data.cooListLookbooks.items.map(({ entries, ...rest }) => ({\n ...rest,\n entries: entries?.items ?? [],\n }));\n },\n });\n};\n\nexport const useCreateLookbook = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (input: CooCreateLookbookInput) => {\n const data = await coolQuery<{ cooCreateLookbook: CooLookbook }>(\n `mutation CooCreateLookbook($input: CooCreateLookbookInput!) {\n cooCreateLookbook(input: $input) { ${LOOKBOOK_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooCreateLookbook;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'lookbooks'] });\n },\n });\n};\n\nexport const useAddLookbookEntry = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (input: CooAddLookbookEntryInput) => {\n const data = await coolQuery<{ cooAddLookbookEntry: { id: string; lookbookId: string } }>(\n `mutation CooAddLookbookEntry($input: CooAddLookbookEntryInput!) {\n cooAddLookbookEntry(input: $input) {\n id lookbookId lookId styleItemId note position createdAt updatedAt\n }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooAddLookbookEntry;\n },\n onSuccess: (entry) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'lookbooks'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'lookbook'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'lookbook', entry.lookbookId] });\n },\n });\n};\n\nexport const useRemoveLookbookEntry = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooRemoveLookbookEntry: boolean }>(\n `mutation CooRemoveLookbookEntry($id: ID!) { cooRemoveLookbookEntry(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return data.cooRemoveLookbookEntry;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'lookbooks'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'lookbook'] });\n },\n });\n};\n\n// ===========================================================================\n// Follow graph (added this release — cooFollow / cooUnfollow / cooIsFollowing)\n// ===========================================================================\n\nconst FOLLOW_PROFILE_FIELDS = `\n id workspaceId ownerId displayName bio visibility\n stylePreferences palette favouriteBrands\n isFollowedByMe followerCount followingCount\n`;\n\n/** Whether the caller currently follows `followeeId`. */\nexport const useIsFollowing = (followeeId: string | undefined) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'is-following', followeeId],\n enabled: Boolean(followeeId),\n queryFn: async () => {\n const data = await coolQuery<{ cooIsFollowing: boolean }>(\n `query CooIsFollowing($followeeId: ID!) { cooIsFollowing(followeeId: $followeeId) }`,\n { followeeId },\n apiGatewayUrl\n );\n return data.cooIsFollowing;\n },\n });\n};\n\nexport const useFollow = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (followeeId: string) => {\n const data = await coolQuery<{ cooFollow: boolean }>(\n `mutation CooFollow($followeeId: ID!) { cooFollow(followeeId: $followeeId) }`,\n { followeeId },\n apiGatewayUrl\n );\n return data.cooFollow;\n },\n onSuccess: (_result, followeeId) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'is-following', followeeId] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'my-following'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'my-followers'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'my-style-profile'] });\n },\n });\n};\n\nexport const useUnfollow = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (followeeId: string) => {\n const data = await coolQuery<{ cooUnfollow: boolean }>(\n `mutation CooUnfollow($followeeId: ID!) { cooUnfollow(followeeId: $followeeId) }`,\n { followeeId },\n apiGatewayUrl\n );\n return data.cooUnfollow;\n },\n onSuccess: (_result, followeeId) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'is-following', followeeId] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'my-following'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'my-followers'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'my-style-profile'] });\n },\n });\n};\n\n/** Style profiles of people the caller follows. */\nexport const useMyFollowing = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'my-following'],\n queryFn: async () => {\n const data = await coolQuery<{ cooMyFollowing: CooStyleProfileConnection }>(\n `query CooMyFollowing {\n cooMyFollowing { items { ${FOLLOW_PROFILE_FIELDS} } pageInfo { cursor hasMore } }\n }`,\n {},\n apiGatewayUrl\n );\n return data.cooMyFollowing.items;\n },\n });\n};\n\n/** Style profiles of people following the caller. */\nexport const useMyFollowers = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'my-followers'],\n queryFn: async () => {\n const data = await coolQuery<{ cooMyFollowers: CooStyleProfileConnection }>(\n `query CooMyFollowers {\n cooMyFollowers { items { ${FOLLOW_PROFILE_FIELDS} } pageInfo { cursor hasMore } }\n }`,\n {},\n apiGatewayUrl\n );\n return data.cooMyFollowers.items;\n },\n });\n};\n\nexport const useLookbook = (id: string | undefined) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'lookbook', id],\n queryFn: async () => {\n const data = await coolQuery<{\n cooLookbook: (CooLookbook & { entries?: CooLookbookEntryConnection | null }) | null;\n }>(\n `query CooLookbook($id: ID!) {\n cooLookbook(id: $id) {\n ${LOOKBOOK_FIELDS}\n entries { items { ${LOOKBOOK_ENTRY_FIELDS} } pageInfo { cursor hasMore } }\n }\n }`,\n { id },\n apiGatewayUrl\n );\n if (!data.cooLookbook) return null;\n const { entries, ...rest } = data.cooLookbook;\n return { ...rest, entries: entries?.items ?? [] };\n },\n enabled: Boolean(id),\n });\n};\n\nexport const useDeleteLookbook = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooDeleteLookbook: boolean }>(\n `mutation CooDeleteLookbook($id: ID!) { cooDeleteLookbook(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return data.cooDeleteLookbook;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'lookbooks'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'lookbook'] });\n },\n });\n};\n\n// ===========================================================================\n// Discovery search\n// ===========================================================================\n\nexport interface SearchStyleItemsArgs {\n input: CooSearchStyleItemsInput;\n pagination?: PaginationInput;\n}\n\nexport const useSearchStyleItems = (args: SearchStyleItemsArgs) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'search-style-items', args],\n queryFn: async () => {\n const data = await coolQuery<{ cooSearchStyleItems: CooStyleItemConnection }>(\n `query CooSearchStyleItems($input: CooSearchStyleItemsInput!, $pagination: PaginationInput) {\n cooSearchStyleItems(input: $input, pagination: $pagination) {\n items { ${STYLE_ITEM_FIELDS} brand { id name handle } }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n input: args.input,\n pagination: args.pagination ?? { limit: 24, offset: 0 },\n },\n apiGatewayUrl\n );\n return data.cooSearchStyleItems;\n },\n });\n};\n\nexport interface SearchLooksArgs {\n input: CooSearchLooksInput;\n pagination?: PaginationInput;\n}\n\nexport const useSearchLooks = (args: SearchLooksArgs) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'search-looks', args],\n queryFn: async () => {\n const data = await coolQuery<{ cooSearchLooks: CooLookConnection }>(\n `query CooSearchLooks($input: CooSearchLooksInput!, $pagination: PaginationInput) {\n cooSearchLooks(input: $input, pagination: $pagination) {\n items { ${LOOK_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n input: args.input,\n pagination: args.pagination ?? { limit: 24, offset: 0 },\n },\n apiGatewayUrl\n );\n return data.cooSearchLooks;\n },\n });\n};\n\n// ===========================================================================\n// Admin curation (gated by the `coolandlovely.admin.curation` feature flag)\n// ===========================================================================\n\nexport const useApproveBrand = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooApproveBrand: CooBrand }>(\n `mutation CooApproveBrand($id: ID!) { cooApproveBrand(id: $id) { ${BRAND_FIELDS} } }`,\n { id },\n apiGatewayUrl\n );\n return data.cooApproveBrand;\n },\n onSuccess: (brand) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'brands'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'brand', brand.id] });\n },\n });\n};\n\nexport const useRejectBrand = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooRejectBrand: CooBrand }>(\n `mutation CooRejectBrand($id: ID!) { cooRejectBrand(id: $id) { ${BRAND_FIELDS} } }`,\n { id },\n apiGatewayUrl\n );\n return data.cooRejectBrand;\n },\n onSuccess: (brand) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'brands'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'brand', brand.id] });\n },\n });\n};\n\nexport const useReviewCollaboration = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async ({ id, input }: { id: string; input: CooReviewCollaborationInput }) => {\n const data = await coolQuery<{ cooReviewCollaboration: CooCollaboration }>(\n `mutation CooReviewCollaboration($id: ID!, $input: CooReviewCollaborationInput!) {\n cooReviewCollaboration(id: $id, input: $input) { ${COLLABORATION_FIELDS} }\n }`,\n { id, input },\n apiGatewayUrl\n );\n return data.cooReviewCollaboration;\n },\n onSuccess: (collab) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'collaborations'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'collaboration', collab.id] });\n },\n });\n};\n\nexport const useFeatureStyleItem = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooFeatureStyleItem: CooStyleItem }>(\n `mutation CooFeatureStyleItem($id: ID!) { cooFeatureStyleItem(id: $id) { ${STYLE_ITEM_FIELDS} } }`,\n { id },\n apiGatewayUrl\n );\n return data.cooFeatureStyleItem;\n },\n onSuccess: (item) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'style-items'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'style-item', item.id] });\n },\n });\n};\n\nexport const useUnfeatureStyleItem = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooUnfeatureStyleItem: CooStyleItem }>(\n `mutation CooUnfeatureStyleItem($id: ID!) { cooUnfeatureStyleItem(id: $id) { ${STYLE_ITEM_FIELDS} } }`,\n { id },\n apiGatewayUrl\n );\n return data.cooUnfeatureStyleItem;\n },\n onSuccess: (item) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'style-items'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'style-item', item.id] });\n },\n });\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"useCoolAndLovelyApi.js","names":[],"sources":["../../../src/coolandlovely/hooks/useCoolAndLovelyApi.ts"],"sourcesContent":["/**\n * CoolAndLovely API hooks\n * @module coolandlovely/hooks\n *\n * Thin, strictly-typed React Query layer over the federated\n * `wspace-coolandlovely-svc` GraphQL contract. Every query/mutation here maps\n * 1:1 to a real `coo*` root field — no mocks. Requests go through the workspace\n * gateway via `graphqlFetch({ gateway: 'workspace', workspaceToken: true })`.\n */\n\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\n\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\n// Imported from the `/fetch` subpath (not the barrel) so it resolves against the\n// MFE's pinned fe-libs, which exposes the helper in fetch but not yet in the\n// graphql barrel index.\nimport { clearGraphqlFetchResponseCache } from '@burdenoff/fe-libs/shared/graphql/fetch';\n\nimport { useCoolAndLovely } from '../context';\nimport type {\n CooAddLookbookEntryInput,\n CooBrand,\n CooBrandConnection,\n CooBrandStatus,\n CooCollaboration,\n CooCollaborationConnection,\n CooCollaborationStatus,\n CooCollection,\n CooCollectionConnection,\n CooCollectionStatus,\n CooCreateBrandInput,\n CooCreateCollaborationInput,\n CooCreateCollectionInput,\n CooCreateLookInput,\n CooCreateLookbookInput,\n CooCreateStyleItemInput,\n CooCreateWardrobeItemInput,\n CooLook,\n CooLookConnection,\n CooLookItemConnection,\n CooLookOccasion,\n CooLookbook,\n CooLookbookEntryConnection,\n CooStyleCategory,\n CooStyleItem,\n CooStyleItemConnection,\n CooStyleItemStatus,\n CooStyleProfile,\n CooStyleProfileConnection,\n CooUpdateBrandInput,\n CooUpdateCollaborationInput,\n CooUpdateCollectionInput,\n CooUpdateLookInput,\n CooUpdateStyleItemInput,\n CooUpdateWardrobeItemInput,\n CooUpsertStyleProfileInput,\n CooWardrobeItem,\n CooWardrobeItemConnection,\n CooWardrobeSource,\n PaginationInput,\n CooSearchStyleItemsInput,\n CooSearchLooksInput,\n CooReviewCollaborationInput,\n} from '../types';\n\n// ---------------------------------------------------------------------------\n// Query key root\n// ---------------------------------------------------------------------------\n\nconst QK = 'coolandlovely';\n\n// ---------------------------------------------------------------------------\n// Low-level fetch wrapper\n// ---------------------------------------------------------------------------\n\nexport const coolQuery = async <TData>(\n query: string,\n variables: Record<string, unknown>,\n baseUrl?: string\n): Promise<TData> => {\n const response = await graphqlFetch<TData>({\n gateway: 'workspace',\n baseUrl,\n query,\n variables,\n workspaceToken: true,\n });\n\n if (response.errors?.length) {\n throw new Error(response.errors[0]?.message ?? 'GraphQL request failed');\n }\n if (!response.data) {\n throw new Error('GraphQL response did not include data');\n }\n // fe-libs graphqlFetch caches every *query* response for ~15s in a global\n // response cache. After a successful mutation we drop that cache so the\n // React Query `invalidateQueries` refetch reads fresh data instead of the\n // stale pre-mutation response (otherwise a like/publish/transition/remove\n // shows no change for up to 15s).\n if (/^\\s*mutation\\b/.test(query)) {\n clearGraphqlFetchResponseCache();\n }\n return response.data;\n};\n\n// ---------------------------------------------------------------------------\n// Reusable GraphQL field selections\n// ---------------------------------------------------------------------------\n\nconst BRAND_FIELDS = `\n id workspaceId name handle tagline bio aesthetics tags websiteUrl\n isFeatured status logo { id } cover { id } createdAt updatedAt\n`;\n\nconst COLLECTION_FIELDS = `\n id workspaceId brandId name description season status tags\n cover { id } publishAt endAt createdAt updatedAt\n`;\n\nconst STYLE_ITEM_FIELDS = `\n id workspaceId brandId collectionId name description category status\n sku price currency colours sizes materials tags image { id }\n createdAt updatedAt\n`;\n\n/** The piece's Burdenoff store catalogue listing state (BOFF-3430). */\nconst STORE_LISTING_FIELDS = `\n storeProductId storeListingStatus storeSyncStatus storeSyncedAt\n`;\n\nconst LOOK_FIELDS = `\n id workspaceId authorId title caption occasion visibility isFeatured\n likeCount saveCount collaborationId image { id } tags publishedAt\n createdAt updatedAt isLikedByMe isSavedByMe\n`;\n\nconst LOOK_ITEM_FIELDS = `\n id workspaceId lookId styleItemId position styling createdAt updatedAt\n styleItem { id name category price currency brand { id name handle } image { id } }\n`;\n\nconst COLLABORATION_FIELDS = `\n id workspaceId brandId creatorId collectionId title brief role status\n compensation currency tags startDate endDate publishedAt createdAt updatedAt\n`;\n\n/** Fields of a collaboration fee (BOFF-9637), shared with the commerce hooks. */\nexport const COLLABORATION_PAYOUT_FIELDS = `\n id collaborationId collaborationTitle brandId creatorId amount currency status paymentProvider\n paidAt earningAvailableAt earningSyncStatus createdAt updatedAt\n`;\n\nconst WARDROBE_FIELDS = `\n id workspaceId profileId name category source brandName colour size notes\n styleItemId purchasePrice currency costPerWear timesWorn lastWornAt tags\n image { id } createdAt updatedAt\n`;\n\nconst PROFILE_FIELDS = `\n id workspaceId ownerId displayName bio visibility stylePreferences\n palette favouriteBrands sizes createdAt updatedAt\n isFollowedByMe followerCount followingCount\n`;\n\nconst LOOKBOOK_FIELDS = `\n id workspaceId ownerId profileId name description visibility tags\n cover { id } createdAt updatedAt\n`;\n\n// ===========================================================================\n// Brands\n// ===========================================================================\n\nexport interface ListBrandsArgs {\n status?: CooBrandStatus;\n featured?: boolean;\n pagination?: PaginationInput;\n}\n\nexport const useBrands = (args: ListBrandsArgs = {}) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'brands', args],\n queryFn: async () => {\n const data = await coolQuery<{ cooListBrands: CooBrandConnection }>(\n `query CooListBrands($status: CooBrandStatus, $featured: Boolean, $pagination: PaginationInput) {\n cooListBrands(status: $status, featured: $featured, pagination: $pagination) {\n items { ${BRAND_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n status: args.status,\n featured: args.featured,\n pagination: args.pagination ?? { limit: 50, offset: 0 },\n },\n apiGatewayUrl\n );\n return data.cooListBrands;\n },\n });\n};\n\n/** Wire shape of `cooBrand` — its nested `collections`/`items` are Connections, flattened below. */\ntype CooBrandWire = Omit<CooBrand, 'collections' | 'items'> & {\n collections?: CooCollectionConnection | null;\n items?: CooStyleItemConnection | null;\n};\n\nexport const useBrand = (id: string | undefined) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'brand', id],\n queryFn: async () => {\n const data = await coolQuery<{ cooBrand: CooBrandWire | null }>(\n `query CooBrand($id: ID!) {\n cooBrand(id: $id) {\n ${BRAND_FIELDS}\n collections { items { ${COLLECTION_FIELDS} } pageInfo { cursor hasMore } }\n items { items { ${STYLE_ITEM_FIELDS} } pageInfo { cursor hasMore } }\n }\n }`,\n { id },\n apiGatewayUrl\n );\n if (!data.cooBrand) return null;\n const { collections, items, ...rest } = data.cooBrand;\n return {\n ...rest,\n collections: collections?.items ?? [],\n items: items?.items ?? [],\n } as CooBrand;\n },\n enabled: Boolean(id),\n });\n};\n\nexport const useCreateBrand = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (input: CooCreateBrandInput) => {\n const data = await coolQuery<{ cooCreateBrand: CooBrand }>(\n `mutation CooCreateBrand($input: CooCreateBrandInput!) {\n cooCreateBrand(input: $input) { ${BRAND_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooCreateBrand;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'brands'] });\n },\n });\n};\n\nexport const useUpdateBrand = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async ({ id, input }: { id: string; input: CooUpdateBrandInput }) => {\n const data = await coolQuery<{ cooUpdateBrand: CooBrand }>(\n `mutation CooUpdateBrand($id: ID!, $input: CooUpdateBrandInput!) {\n cooUpdateBrand(id: $id, input: $input) { ${BRAND_FIELDS} }\n }`,\n { id, input },\n apiGatewayUrl\n );\n return data.cooUpdateBrand;\n },\n onSuccess: (brand) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'brands'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'brand', brand.id] });\n },\n });\n};\n\nexport const useTransitionBrand = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async ({ id, status }: { id: string; status: CooBrandStatus }) => {\n const data = await coolQuery<{ cooTransitionBrand: CooBrand }>(\n `mutation CooTransitionBrand($id: ID!, $status: CooBrandStatus!) {\n cooTransitionBrand(id: $id, status: $status) { ${BRAND_FIELDS} }\n }`,\n { id, status },\n apiGatewayUrl\n );\n return data.cooTransitionBrand;\n },\n onSuccess: (brand) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'brands'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'brand', brand.id] });\n },\n });\n};\n\nexport const useArchiveBrand = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooArchiveBrand: boolean }>(\n `mutation CooArchiveBrand($id: ID!) { cooArchiveBrand(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return data.cooArchiveBrand;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'brands'] });\n },\n });\n};\n\n// ===========================================================================\n// Collections\n// ===========================================================================\n\nexport interface ListCollectionsArgs {\n brandId?: string;\n status?: CooCollectionStatus;\n}\n\nexport const useCollections = (args: ListCollectionsArgs = {}) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'collections', args],\n queryFn: async () => {\n const data = await coolQuery<{ cooListCollections: CooCollectionConnection }>(\n `query CooListCollections($brandId: ID, $status: CooCollectionStatus) {\n cooListCollections(brandId: $brandId, status: $status) {\n items { ${COLLECTION_FIELDS} brand { id name handle } }\n pageInfo { cursor hasMore }\n }\n }`,\n { brandId: args.brandId, status: args.status },\n apiGatewayUrl\n );\n return data.cooListCollections.items;\n },\n });\n};\n\n/** Wire shape of `cooCollection` — its nested `items` is a Connection, flattened below. */\ntype CooCollectionWire = Omit<CooCollection, 'items'> & { items?: CooStyleItemConnection | null };\n\nexport const useCollection = (id: string | undefined) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'collection', id],\n queryFn: async () => {\n const data = await coolQuery<{ cooCollection: CooCollectionWire | null }>(\n `query CooCollection($id: ID!) {\n cooCollection(id: $id) {\n ${COLLECTION_FIELDS}\n brand { id name handle }\n items { items { ${STYLE_ITEM_FIELDS} } pageInfo { cursor hasMore } }\n }\n }`,\n { id },\n apiGatewayUrl\n );\n if (!data.cooCollection) return null;\n const { items, ...rest } = data.cooCollection;\n return { ...rest, items: items?.items ?? [] } as CooCollection;\n },\n enabled: Boolean(id),\n });\n};\n\nexport const useCreateCollection = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (input: CooCreateCollectionInput) => {\n const data = await coolQuery<{ cooCreateCollection: CooCollection }>(\n `mutation CooCreateCollection($input: CooCreateCollectionInput!) {\n cooCreateCollection(input: $input) { ${COLLECTION_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooCreateCollection;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'collections'] });\n },\n });\n};\n\nexport const useUpdateCollection = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async ({ id, input }: { id: string; input: CooUpdateCollectionInput }) => {\n const data = await coolQuery<{ cooUpdateCollection: CooCollection }>(\n `mutation CooUpdateCollection($id: ID!, $input: CooUpdateCollectionInput!) {\n cooUpdateCollection(id: $id, input: $input) { ${COLLECTION_FIELDS} }\n }`,\n { id, input },\n apiGatewayUrl\n );\n return data.cooUpdateCollection;\n },\n onSuccess: (collection) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'collections'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'collection', collection.id] });\n },\n });\n};\n\nexport const usePublishCollection = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooPublishCollection: CooCollection }>(\n `mutation CooPublishCollection($id: ID!) {\n cooPublishCollection(id: $id) { ${COLLECTION_FIELDS} }\n }`,\n { id },\n apiGatewayUrl\n );\n return data.cooPublishCollection;\n },\n onSuccess: (collection) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'collections'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'collection', collection.id] });\n },\n });\n};\n\nexport const useArchiveCollection = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooArchiveCollection: boolean }>(\n `mutation CooArchiveCollection($id: ID!) { cooArchiveCollection(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return data.cooArchiveCollection;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'collections'] });\n },\n });\n};\n\n// ===========================================================================\n// Style Items\n// ===========================================================================\n\nexport interface ListStyleItemsArgs {\n brandId?: string;\n collectionId?: string;\n category?: CooStyleCategory;\n status?: CooStyleItemStatus;\n pagination?: PaginationInput;\n}\n\nexport const useStyleItems = (args: ListStyleItemsArgs = {}) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'style-items', args],\n queryFn: async () => {\n const data = await coolQuery<{ cooListStyleItems: CooStyleItemConnection }>(\n `query CooListStyleItems(\n $brandId: ID, $collectionId: ID, $category: CooStyleCategory,\n $status: CooStyleItemStatus, $pagination: PaginationInput\n ) {\n cooListStyleItems(\n brandId: $brandId, collectionId: $collectionId, category: $category,\n status: $status, pagination: $pagination\n ) {\n items { ${STYLE_ITEM_FIELDS} brand { id name handle } }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n brandId: args.brandId,\n collectionId: args.collectionId,\n category: args.category,\n status: args.status,\n pagination: args.pagination ?? { limit: 50, offset: 0 },\n },\n apiGatewayUrl\n );\n return data.cooListStyleItems;\n },\n });\n};\n\nexport const useStyleItem = (id: string | undefined) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'style-item', id],\n queryFn: async () => {\n const data = await coolQuery<{ cooStyleItem: CooStyleItem | null }>(\n `query CooStyleItem($id: ID!) {\n cooStyleItem(id: $id) {\n ${STYLE_ITEM_FIELDS}\n ${STORE_LISTING_FIELDS}\n brand { id name handle }\n collection { id name }\n }\n }`,\n { id },\n apiGatewayUrl\n );\n return data.cooStyleItem;\n },\n enabled: Boolean(id),\n });\n};\n\nexport const useCreateStyleItem = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (input: CooCreateStyleItemInput) => {\n const data = await coolQuery<{ cooCreateStyleItem: CooStyleItem }>(\n `mutation CooCreateStyleItem($input: CooCreateStyleItemInput!) {\n cooCreateStyleItem(input: $input) { ${STYLE_ITEM_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooCreateStyleItem;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'style-items'] });\n },\n });\n};\n\nexport const useUpdateStyleItem = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async ({ id, input }: { id: string; input: CooUpdateStyleItemInput }) => {\n const data = await coolQuery<{ cooUpdateStyleItem: CooStyleItem }>(\n `mutation CooUpdateStyleItem($id: ID!, $input: CooUpdateStyleItemInput!) {\n cooUpdateStyleItem(id: $id, input: $input) { ${STYLE_ITEM_FIELDS} }\n }`,\n { id, input },\n apiGatewayUrl\n );\n return data.cooUpdateStyleItem;\n },\n onSuccess: (item) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'style-items'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'style-item', item.id] });\n // Sizes or colours may have changed, and with them the variants that hold stock.\n void queryClient.invalidateQueries({ queryKey: [QK, 'style-item-inventory', item.id] });\n },\n });\n};\n\n/**\n * Re-drive the push of a piece to its Burdenoff store catalogue listing\n * (`cooSyncStyleItemStoreListing`, BOFF-3430). Listings normally follow every\n * change automatically; this is the manual retry for a FAILED sync. The\n * service records a failed push on the piece rather than throwing, so the\n * returned item carries the new outcome either way.\n */\nexport const useSyncStyleItemStoreListing = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooSyncStyleItemStoreListing: CooStyleItem }>(\n `mutation CooSyncStyleItemStoreListing($id: ID!) {\n cooSyncStyleItemStoreListing(id: $id) { id ${STORE_LISTING_FIELDS} }\n }`,\n { id },\n apiGatewayUrl\n );\n return data.cooSyncStyleItemStoreListing;\n },\n onSuccess: (synced) => {\n queryClient.setQueryData<CooStyleItem | null>([QK, 'style-item', synced.id], (prev) =>\n prev ? { ...prev, ...synced } : prev\n );\n void queryClient.invalidateQueries({ queryKey: [QK, 'style-item', synced.id] });\n },\n });\n};\n\nexport const useArchiveStyleItem = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooArchiveStyleItem: boolean }>(\n `mutation CooArchiveStyleItem($id: ID!) { cooArchiveStyleItem(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return data.cooArchiveStyleItem;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'style-items'] });\n },\n });\n};\n\n// ===========================================================================\n// Looks\n// ===========================================================================\n\nexport interface ListLooksArgs {\n authorId?: string;\n occasion?: CooLookOccasion;\n featured?: boolean;\n pagination?: PaginationInput;\n}\n\nexport const useLooks = (args: ListLooksArgs = {}) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'looks', args],\n queryFn: async () => {\n const data = await coolQuery<{ cooListLooks: CooLookConnection }>(\n `query CooListLooks(\n $authorId: ID, $occasion: CooLookOccasion, $featured: Boolean, $pagination: PaginationInput\n ) {\n cooListLooks(authorId: $authorId, occasion: $occasion, featured: $featured, pagination: $pagination) {\n items { ${LOOK_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n authorId: args.authorId,\n occasion: args.occasion,\n featured: args.featured,\n pagination: args.pagination ?? { limit: 50, offset: 0 },\n },\n apiGatewayUrl\n );\n return data.cooListLooks;\n },\n });\n};\n\n/** Wire shape of `cooLook` — its nested `items` is a Connection, flattened below. */\ntype CooLookWire = Omit<CooLook, 'items'> & { items?: CooLookItemConnection | null };\n\nexport const useLook = (id: string | undefined) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'look', id],\n queryFn: async () => {\n const data = await coolQuery<{ cooLook: CooLookWire | null }>(\n `query CooLook($id: ID!) {\n cooLook(id: $id) {\n ${LOOK_FIELDS}\n items { items { ${LOOK_ITEM_FIELDS} } pageInfo { cursor hasMore } }\n }\n }`,\n { id },\n apiGatewayUrl\n );\n if (!data.cooLook) return null;\n const { items, ...rest } = data.cooLook;\n return { ...rest, items: items?.items ?? [] } as CooLook;\n },\n enabled: Boolean(id),\n });\n};\n\nexport const useLooksWithItems = (args: ListLooksArgs = {}) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'looks-with-items', args],\n queryFn: async () => {\n const data = await coolQuery<{\n cooListLooks: { items: CooLookWire[]; pageInfo: CooLookConnection['pageInfo'] };\n }>(\n `query CooListLooksWithItems(\n $authorId: ID, $occasion: CooLookOccasion, $featured: Boolean, $pagination: PaginationInput\n ) {\n cooListLooks(authorId: $authorId, occasion: $occasion, featured: $featured, pagination: $pagination) {\n items { ${LOOK_FIELDS} items { items { ${LOOK_ITEM_FIELDS} } pageInfo { cursor hasMore } } }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n authorId: args.authorId,\n occasion: args.occasion,\n featured: args.featured,\n pagination: args.pagination ?? { limit: 50, offset: 0 },\n },\n apiGatewayUrl\n );\n return {\n items: data.cooListLooks.items.map(\n ({ items, ...rest }) => ({ ...rest, items: items?.items ?? [] }) as CooLook\n ),\n pageInfo: data.cooListLooks.pageInfo,\n };\n },\n });\n};\n\nexport const useCreateLook = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (input: CooCreateLookInput) => {\n const data = await coolQuery<{ cooCreateLook: CooLook }>(\n `mutation CooCreateLook($input: CooCreateLookInput!) {\n cooCreateLook(input: $input) { ${LOOK_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooCreateLook;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks-with-items'] });\n },\n });\n};\n\nexport const useUpdateLook = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async ({ id, input }: { id: string; input: CooUpdateLookInput }) => {\n const data = await coolQuery<{ cooUpdateLook: CooLook }>(\n `mutation CooUpdateLook($id: ID!, $input: CooUpdateLookInput!) {\n cooUpdateLook(id: $id, input: $input) { ${LOOK_FIELDS} }\n }`,\n { id, input },\n apiGatewayUrl\n );\n return data.cooUpdateLook;\n },\n onSuccess: (look) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks-with-items'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'look', look.id] });\n },\n });\n};\n\nexport const usePublishLook = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooPublishLook: CooLook }>(\n `mutation CooPublishLook($id: ID!) { cooPublishLook(id: $id) { ${LOOK_FIELDS} } }`,\n { id },\n apiGatewayUrl\n );\n return data.cooPublishLook;\n },\n onSuccess: (look) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks-with-items'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'look', look.id] });\n },\n });\n};\n\nexport const useLikeLook = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooLikeLook: CooLook }>(\n `mutation CooLikeLook($id: ID!) { cooLikeLook(id: $id) { ${LOOK_FIELDS} } }`,\n { id },\n apiGatewayUrl\n );\n return data.cooLikeLook;\n },\n onSuccess: (look) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks-with-items'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'look', look.id] });\n },\n });\n};\n\nexport const useUnlikeLook = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooUnlikeLook: CooLook }>(\n `mutation CooUnlikeLook($id: ID!) { cooUnlikeLook(id: $id) { ${LOOK_FIELDS} } }`,\n { id },\n apiGatewayUrl\n );\n return data.cooUnlikeLook;\n },\n onSuccess: (look) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks-with-items'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'look', look.id] });\n },\n });\n};\n\nexport const useSaveLook = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooSaveLook: CooLook }>(\n `mutation CooSaveLook($id: ID!) { cooSaveLook(id: $id) { ${LOOK_FIELDS} } }`,\n { id },\n apiGatewayUrl\n );\n return data.cooSaveLook;\n },\n onSuccess: (look) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks-with-items'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'look', look.id] });\n },\n });\n};\n\nexport const useUnsaveLook = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooUnsaveLook: CooLook }>(\n `mutation CooUnsaveLook($id: ID!) { cooUnsaveLook(id: $id) { ${LOOK_FIELDS} } }`,\n { id },\n apiGatewayUrl\n );\n return data.cooUnsaveLook;\n },\n onSuccess: (look) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks-with-items'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'look', look.id] });\n },\n });\n};\n\nexport const useDeleteLook = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooDeleteLook: boolean }>(\n `mutation CooDeleteLook($id: ID!) { cooDeleteLook(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return data.cooDeleteLook;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'looks-with-items'] });\n },\n });\n};\n\n// ===========================================================================\n// Collaborations\n// ===========================================================================\n\nexport interface ListCollaborationsArgs {\n brandId?: string;\n creatorId?: string;\n status?: CooCollaborationStatus;\n}\n\nexport const useCollaborations = (args: ListCollaborationsArgs = {}) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'collaborations', args],\n queryFn: async () => {\n const data = await coolQuery<{ cooListCollaborations: CooCollaborationConnection }>(\n `query CooListCollaborations($brandId: ID, $creatorId: ID, $status: CooCollaborationStatus) {\n cooListCollaborations(brandId: $brandId, creatorId: $creatorId, status: $status) {\n items { ${COLLABORATION_FIELDS} brand { id name handle logo { id } } }\n pageInfo { cursor hasMore }\n }\n }`,\n { brandId: args.brandId, creatorId: args.creatorId, status: args.status },\n apiGatewayUrl\n );\n return data.cooListCollaborations.items;\n },\n });\n};\n\n/** Wire shape of `cooCollaboration` — its nested `looks` is a Connection, flattened below. */\ntype CooCollaborationWire = Omit<CooCollaboration, 'looks'> & { looks?: CooLookConnection | null };\n\nexport const useCollaboration = (id: string | undefined) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'collaboration', id],\n queryFn: async () => {\n const data = await coolQuery<{ cooCollaboration: CooCollaborationWire | null }>(\n `query CooCollaboration($id: ID!) {\n cooCollaboration(id: $id) {\n ${COLLABORATION_FIELDS}\n brand { id name handle logo { id } }\n looks { items { ${LOOK_FIELDS} } pageInfo { cursor hasMore } }\n payout { ${COLLABORATION_PAYOUT_FIELDS} }\n }\n }`,\n { id },\n apiGatewayUrl\n );\n if (!data.cooCollaboration) return null;\n const { looks, ...rest } = data.cooCollaboration;\n return { ...rest, looks: looks?.items ?? [] } as CooCollaboration;\n },\n enabled: Boolean(id),\n });\n};\n\nexport const useCreateCollaboration = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (input: CooCreateCollaborationInput) => {\n const data = await coolQuery<{ cooCreateCollaboration: CooCollaboration }>(\n `mutation CooCreateCollaboration($input: CooCreateCollaborationInput!) {\n cooCreateCollaboration(input: $input) { ${COLLABORATION_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooCreateCollaboration;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'collaborations'] });\n },\n });\n};\n\nexport const useUpdateCollaboration = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async ({ id, input }: { id: string; input: CooUpdateCollaborationInput }) => {\n const data = await coolQuery<{ cooUpdateCollaboration: CooCollaboration }>(\n `mutation CooUpdateCollaboration($id: ID!, $input: CooUpdateCollaborationInput!) {\n cooUpdateCollaboration(id: $id, input: $input) {\n ${COLLABORATION_FIELDS}\n brand { id name handle logo { id } }\n }\n }`,\n { id, input },\n apiGatewayUrl\n );\n return data.cooUpdateCollaboration;\n },\n onSuccess: (collab) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'collaborations'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'collaboration', collab.id] });\n },\n });\n};\n\nexport const useTransitionCollaboration = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async ({ id, status }: { id: string; status: CooCollaborationStatus }) => {\n const data = await coolQuery<{ cooTransitionCollaboration: CooCollaboration }>(\n `mutation CooTransitionCollaboration($id: ID!, $status: CooCollaborationStatus!) {\n cooTransitionCollaboration(id: $id, status: $status) { ${COLLABORATION_FIELDS} }\n }`,\n { id, status },\n apiGatewayUrl\n );\n return data.cooTransitionCollaboration;\n },\n onSuccess: (collab) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'collaborations'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'collaboration', collab.id] });\n },\n });\n};\n\n/** Delete a still-PROPOSED collaboration (the svc rejects this once it has moved past PROPOSED). */\nexport const useDeleteCollaboration = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooDeleteCollaboration: boolean }>(\n `mutation CooDeleteCollaboration($id: ID!) { cooDeleteCollaboration(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return data.cooDeleteCollaboration;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'collaborations'] });\n },\n });\n};\n\n// ===========================================================================\n// Wardrobe (self-scoped)\n// ===========================================================================\n\nexport interface ListWardrobeArgs {\n category?: CooStyleCategory;\n source?: CooWardrobeSource;\n}\n\nexport const useWardrobeItems = (args: ListWardrobeArgs = {}) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'wardrobe', args],\n queryFn: async () => {\n const data = await coolQuery<{ cooListWardrobeItems: CooWardrobeItemConnection }>(\n `query CooListWardrobeItems($category: CooStyleCategory, $source: CooWardrobeSource) {\n cooListWardrobeItems(category: $category, source: $source) {\n items { ${WARDROBE_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n { category: args.category, source: args.source },\n apiGatewayUrl\n );\n return data.cooListWardrobeItems.items;\n },\n });\n};\n\nexport const useCreateWardrobeItem = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (input: CooCreateWardrobeItemInput) => {\n const data = await coolQuery<{ cooCreateWardrobeItem: CooWardrobeItem }>(\n `mutation CooCreateWardrobeItem($input: CooCreateWardrobeItemInput!) {\n cooCreateWardrobeItem(input: $input) { ${WARDROBE_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooCreateWardrobeItem;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'wardrobe'] });\n },\n });\n};\n\nexport const useUpdateWardrobeItem = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async ({ id, input }: { id: string; input: CooUpdateWardrobeItemInput }) => {\n const data = await coolQuery<{ cooUpdateWardrobeItem: CooWardrobeItem }>(\n `mutation CooUpdateWardrobeItem($id: ID!, $input: CooUpdateWardrobeItemInput!) {\n cooUpdateWardrobeItem(id: $id, input: $input) { ${WARDROBE_FIELDS} }\n }`,\n { id, input },\n apiGatewayUrl\n );\n return data.cooUpdateWardrobeItem;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'wardrobe'] });\n },\n });\n};\n\nexport const useLogWardrobeWear = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooLogWardrobeWear: CooWardrobeItem }>(\n `mutation CooLogWardrobeWear($id: ID!) {\n cooLogWardrobeWear(id: $id) { ${WARDROBE_FIELDS} }\n }`,\n { id },\n apiGatewayUrl\n );\n return data.cooLogWardrobeWear;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'wardrobe'] });\n },\n });\n};\n\nexport const useRemoveWardrobeItem = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooRemoveWardrobeItem: boolean }>(\n `mutation CooRemoveWardrobeItem($id: ID!) { cooRemoveWardrobeItem(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return data.cooRemoveWardrobeItem;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'wardrobe'] });\n },\n });\n};\n\n// ===========================================================================\n// Style Profile (self-scoped)\n// ===========================================================================\n\nexport const useMyStyleProfile = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'my-style-profile'],\n queryFn: async () => {\n const data = await coolQuery<{ cooMyStyleProfile: CooStyleProfile | null }>(\n `query CooMyStyleProfile { cooMyStyleProfile { ${PROFILE_FIELDS} } }`,\n {},\n apiGatewayUrl\n );\n return data.cooMyStyleProfile;\n },\n });\n};\n\n/**\n * A style profile by its own id, honoring CooVisibility (PRIVATE/FOLLOWERS\n * gated server-side). Returns null when not found or not visible to the\n * caller. Disabled until `id` is provided.\n */\nexport const useStyleProfile = (id: string | undefined) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'style-profile', id],\n queryFn: async () => {\n const data = await coolQuery<{ cooStyleProfile: CooStyleProfile | null }>(\n `query CooStyleProfile($id: ID!) { cooStyleProfile(id: $id) { ${PROFILE_FIELDS} } }`,\n { id },\n apiGatewayUrl\n );\n return data.cooStyleProfile;\n },\n enabled: Boolean(id),\n });\n};\n\n/**\n * Same visibility gate as `useStyleProfile`, looked up by the profile\n * owner's actor id — powers `/profile/:userId` (the public profile route\n * reached from an author's name/avatar on a Look/Discover/Collaboration\n * card). Disabled until `ownerId` is provided.\n */\nexport const useStyleProfileByOwner = (ownerId: string | undefined) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'style-profile-by-owner', ownerId],\n queryFn: async () => {\n const data = await coolQuery<{ cooStyleProfileByOwner: CooStyleProfile | null }>(\n `query CooStyleProfileByOwner($ownerId: ID!) {\n cooStyleProfileByOwner(ownerId: $ownerId) { ${PROFILE_FIELDS} }\n }`,\n { ownerId },\n apiGatewayUrl\n );\n return data.cooStyleProfileByOwner;\n },\n enabled: Boolean(ownerId),\n });\n};\n\nexport const useUpsertStyleProfile = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (input: CooUpsertStyleProfileInput) => {\n const data = await coolQuery<{ cooUpsertStyleProfile: CooStyleProfile }>(\n `mutation CooUpsertStyleProfile($input: CooUpsertStyleProfileInput!) {\n cooUpsertStyleProfile(input: $input) { ${PROFILE_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooUpsertStyleProfile;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'my-style-profile'] });\n },\n });\n};\n\n// ===========================================================================\n// Lookbooks\n// ===========================================================================\n\n/** The plain `CooLookbookEntry` field selection reused across lookbook queries. */\nconst LOOKBOOK_ENTRY_FIELDS =\n 'id workspaceId lookbookId lookId styleItemId note position createdAt updatedAt';\n\nexport const useLookbooks = (ownerId?: string) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'lookbooks', ownerId],\n queryFn: async () => {\n const data = await coolQuery<{\n cooListLookbooks: {\n items: (CooLookbook & { entries?: CooLookbookEntryConnection | null })[];\n pageInfo: unknown;\n };\n }>(\n `query CooListLookbooks($ownerId: ID) {\n cooListLookbooks(ownerId: $ownerId) {\n items {\n ${LOOKBOOK_FIELDS}\n entries { items { ${LOOKBOOK_ENTRY_FIELDS} } pageInfo { cursor hasMore } }\n }\n pageInfo { cursor hasMore }\n }\n }`,\n { ownerId },\n apiGatewayUrl\n );\n return data.cooListLookbooks.items.map(({ entries, ...rest }) => ({\n ...rest,\n entries: entries?.items ?? [],\n }));\n },\n });\n};\n\nexport const useCreateLookbook = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (input: CooCreateLookbookInput) => {\n const data = await coolQuery<{ cooCreateLookbook: CooLookbook }>(\n `mutation CooCreateLookbook($input: CooCreateLookbookInput!) {\n cooCreateLookbook(input: $input) { ${LOOKBOOK_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooCreateLookbook;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'lookbooks'] });\n },\n });\n};\n\nexport const useAddLookbookEntry = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (input: CooAddLookbookEntryInput) => {\n const data = await coolQuery<{ cooAddLookbookEntry: { id: string; lookbookId: string } }>(\n `mutation CooAddLookbookEntry($input: CooAddLookbookEntryInput!) {\n cooAddLookbookEntry(input: $input) {\n id lookbookId lookId styleItemId note position createdAt updatedAt\n }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooAddLookbookEntry;\n },\n onSuccess: (entry) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'lookbooks'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'lookbook'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'lookbook', entry.lookbookId] });\n },\n });\n};\n\nexport const useRemoveLookbookEntry = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooRemoveLookbookEntry: boolean }>(\n `mutation CooRemoveLookbookEntry($id: ID!) { cooRemoveLookbookEntry(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return data.cooRemoveLookbookEntry;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'lookbooks'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'lookbook'] });\n },\n });\n};\n\n// ===========================================================================\n// Follow graph (added this release — cooFollow / cooUnfollow / cooIsFollowing)\n// ===========================================================================\n\nconst FOLLOW_PROFILE_FIELDS = `\n id workspaceId ownerId displayName bio visibility\n stylePreferences palette favouriteBrands\n isFollowedByMe followerCount followingCount\n`;\n\n/** Whether the caller currently follows `followeeId`. */\nexport const useIsFollowing = (followeeId: string | undefined) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'is-following', followeeId],\n enabled: Boolean(followeeId),\n queryFn: async () => {\n const data = await coolQuery<{ cooIsFollowing: boolean }>(\n `query CooIsFollowing($followeeId: ID!) { cooIsFollowing(followeeId: $followeeId) }`,\n { followeeId },\n apiGatewayUrl\n );\n return data.cooIsFollowing;\n },\n });\n};\n\nexport const useFollow = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (followeeId: string) => {\n const data = await coolQuery<{ cooFollow: boolean }>(\n `mutation CooFollow($followeeId: ID!) { cooFollow(followeeId: $followeeId) }`,\n { followeeId },\n apiGatewayUrl\n );\n return data.cooFollow;\n },\n onSuccess: (_result, followeeId) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'is-following', followeeId] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'my-following'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'my-followers'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'my-style-profile'] });\n },\n });\n};\n\nexport const useUnfollow = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (followeeId: string) => {\n const data = await coolQuery<{ cooUnfollow: boolean }>(\n `mutation CooUnfollow($followeeId: ID!) { cooUnfollow(followeeId: $followeeId) }`,\n { followeeId },\n apiGatewayUrl\n );\n return data.cooUnfollow;\n },\n onSuccess: (_result, followeeId) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'is-following', followeeId] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'my-following'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'my-followers'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'my-style-profile'] });\n },\n });\n};\n\n/** Style profiles of people the caller follows. */\nexport const useMyFollowing = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'my-following'],\n queryFn: async () => {\n const data = await coolQuery<{ cooMyFollowing: CooStyleProfileConnection }>(\n `query CooMyFollowing {\n cooMyFollowing { items { ${FOLLOW_PROFILE_FIELDS} } pageInfo { cursor hasMore } }\n }`,\n {},\n apiGatewayUrl\n );\n return data.cooMyFollowing.items;\n },\n });\n};\n\n/** Style profiles of people following the caller. */\nexport const useMyFollowers = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'my-followers'],\n queryFn: async () => {\n const data = await coolQuery<{ cooMyFollowers: CooStyleProfileConnection }>(\n `query CooMyFollowers {\n cooMyFollowers { items { ${FOLLOW_PROFILE_FIELDS} } pageInfo { cursor hasMore } }\n }`,\n {},\n apiGatewayUrl\n );\n return data.cooMyFollowers.items;\n },\n });\n};\n\nexport const useLookbook = (id: string | undefined) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'lookbook', id],\n queryFn: async () => {\n const data = await coolQuery<{\n cooLookbook: (CooLookbook & { entries?: CooLookbookEntryConnection | null }) | null;\n }>(\n `query CooLookbook($id: ID!) {\n cooLookbook(id: $id) {\n ${LOOKBOOK_FIELDS}\n entries { items { ${LOOKBOOK_ENTRY_FIELDS} } pageInfo { cursor hasMore } }\n }\n }`,\n { id },\n apiGatewayUrl\n );\n if (!data.cooLookbook) return null;\n const { entries, ...rest } = data.cooLookbook;\n return { ...rest, entries: entries?.items ?? [] };\n },\n enabled: Boolean(id),\n });\n};\n\nexport const useDeleteLookbook = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooDeleteLookbook: boolean }>(\n `mutation CooDeleteLookbook($id: ID!) { cooDeleteLookbook(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return data.cooDeleteLookbook;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'lookbooks'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'lookbook'] });\n },\n });\n};\n\n// ===========================================================================\n// Discovery search\n// ===========================================================================\n\nexport interface SearchStyleItemsArgs {\n input: CooSearchStyleItemsInput;\n pagination?: PaginationInput;\n /**\n * Run the search only while this is true. Every call is metered against the\n * workspace's `coolandlovely.searches.count` quota, so callers must not fire\n * a search the shopper has not asked for (for example a hidden tab).\n */\n enabled?: boolean;\n}\n\nexport const useSearchStyleItems = ({ enabled = true, ...args }: SearchStyleItemsArgs) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'search-style-items', args],\n enabled,\n queryFn: async () => {\n const data = await coolQuery<{ cooSearchStyleItems: CooStyleItemConnection }>(\n `query CooSearchStyleItems($input: CooSearchStyleItemsInput!, $pagination: PaginationInput) {\n cooSearchStyleItems(input: $input, pagination: $pagination) {\n items { ${STYLE_ITEM_FIELDS} brand { id name handle } }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n input: args.input,\n pagination: args.pagination ?? { limit: 24, offset: 0 },\n },\n apiGatewayUrl\n );\n return data.cooSearchStyleItems;\n },\n });\n};\n\nexport interface SearchLooksArgs {\n input: CooSearchLooksInput;\n pagination?: PaginationInput;\n /**\n * Run the search only while this is true. Every call is metered against the\n * workspace's `coolandlovely.searches.count` quota, so callers must not fire\n * a search the shopper has not asked for (for example a hidden tab).\n */\n enabled?: boolean;\n}\n\nexport const useSearchLooks = ({ enabled = true, ...args }: SearchLooksArgs) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'search-looks', args],\n enabled,\n queryFn: async () => {\n const data = await coolQuery<{ cooSearchLooks: CooLookConnection }>(\n `query CooSearchLooks($input: CooSearchLooksInput!, $pagination: PaginationInput) {\n cooSearchLooks(input: $input, pagination: $pagination) {\n items { ${LOOK_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n input: args.input,\n pagination: args.pagination ?? { limit: 24, offset: 0 },\n },\n apiGatewayUrl\n );\n return data.cooSearchLooks;\n },\n });\n};\n\n// ===========================================================================\n// Admin curation (gated by the `coolandlovely.admin.curation` feature flag)\n// ===========================================================================\n\nexport const useApproveBrand = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooApproveBrand: CooBrand }>(\n `mutation CooApproveBrand($id: ID!) { cooApproveBrand(id: $id) { ${BRAND_FIELDS} } }`,\n { id },\n apiGatewayUrl\n );\n return data.cooApproveBrand;\n },\n onSuccess: (brand) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'brands'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'brand', brand.id] });\n },\n });\n};\n\nexport const useRejectBrand = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooRejectBrand: CooBrand }>(\n `mutation CooRejectBrand($id: ID!) { cooRejectBrand(id: $id) { ${BRAND_FIELDS} } }`,\n { id },\n apiGatewayUrl\n );\n return data.cooRejectBrand;\n },\n onSuccess: (brand) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'brands'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'brand', brand.id] });\n },\n });\n};\n\nexport const useReviewCollaboration = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async ({ id, input }: { id: string; input: CooReviewCollaborationInput }) => {\n const data = await coolQuery<{ cooReviewCollaboration: CooCollaboration }>(\n `mutation CooReviewCollaboration($id: ID!, $input: CooReviewCollaborationInput!) {\n cooReviewCollaboration(id: $id, input: $input) { ${COLLABORATION_FIELDS} }\n }`,\n { id, input },\n apiGatewayUrl\n );\n return data.cooReviewCollaboration;\n },\n onSuccess: (collab) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'collaborations'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'collaboration', collab.id] });\n },\n });\n};\n\nexport const useFeatureStyleItem = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooFeatureStyleItem: CooStyleItem }>(\n `mutation CooFeatureStyleItem($id: ID!) { cooFeatureStyleItem(id: $id) { ${STYLE_ITEM_FIELDS} } }`,\n { id },\n apiGatewayUrl\n );\n return data.cooFeatureStyleItem;\n },\n onSuccess: (item) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'style-items'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'style-item', item.id] });\n },\n });\n};\n\nexport const useUnfeatureStyleItem = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooUnfeatureStyleItem: CooStyleItem }>(\n `mutation CooUnfeatureStyleItem($id: ID!) { cooUnfeatureStyleItem(id: $id) { ${STYLE_ITEM_FIELDS} } }`,\n { id },\n apiGatewayUrl\n );\n return data.cooUnfeatureStyleItem;\n },\n onSuccess: (item) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'style-items'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'style-item', item.id] });\n },\n });\n};\n"],"mappings":";;;;;;AAqEA,IAAM,IAAK,iBAME,IAAY,OACvB,GACA,GACA,MACmB;CACnB,IAAM,IAAW,MAAM,EAAoB;EACzC,SAAS;EACT;EACA;EACA;EACA,gBAAgB;EACjB,CAAC;AAEF,KAAI,EAAS,QAAQ,OACnB,OAAU,MAAM,EAAS,OAAO,IAAI,WAAW,yBAAyB;AAE1E,KAAI,CAAC,EAAS,KACZ,OAAU,MAAM,wCAAwC;AAU1D,QAHI,iBAAiB,KAAK,EAAM,IAC9B,GAAgC,EAE3B,EAAS;GAOZ,IAAe,6IAKf,IAAoB,wHAKpB,IAAoB,qKAOpB,IAAuB,yEAIvB,IAAc,kMAMd,IAAmB,uKAKnB,IAAuB,+JAMhB,IAA8B,2KAKrC,IAAkB,mMAMlB,IAAiB,gLAMjB,IAAkB,+GAeX,MAAa,IAAuB,EAAE,KAAK;CACtD,IAAM,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAS;EACd,UAAU;GAAC;GAAI;GAAU;GAAK;EAC9B,SAAS,aACM,MAAM,EACjB;;sBAEc,EAAa;;;YAI3B;GACE,QAAQ,EAAK;GACb,UAAU,EAAK;GACf,YAAY,EAAK,cAAc;IAAE,OAAO;IAAI,QAAQ;IAAG;GACxD,EACD,EACD,EACW;EAEf,CAAC;GASS,MAAY,MAA2B;CAClD,IAAM,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAS;EACd,UAAU;GAAC;GAAI;GAAS;GAAG;EAC3B,SAAS,YAAY;GACnB,IAAM,IAAO,MAAM,EACjB;;cAEM,EAAa;oCACS,EAAkB;8BACxB,EAAkB;;YAGxC,EAAE,OAAI,EACN,EACD;AACD,OAAI,CAAC,EAAK,SAAU,QAAO;GAC3B,IAAM,EAAE,gBAAa,UAAO,GAAG,MAAS,EAAK;AAC7C,UAAO;IACL,GAAG;IACH,aAAa,GAAa,SAAS,EAAE;IACrC,OAAO,GAAO,SAAS,EAAE;IAC1B;;EAEH,SAAS,EAAQ;EAClB,CAAC;GAGS,UAAuB;CAClC,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB;4CACoC,EAAa;YAEjD,EAAE,UAAO,EACT,EACD,EACW;EAEd,iBAAiB;AACV,KAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,SAAS,EAAE,CAAC;;EAEnE,CAAC;GAGS,UAAuB;CAClC,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,EAAE,OAAI,gBACV,MAAM,EACjB;qDAC6C,EAAa;YAE1D;GAAE;GAAI;GAAO,EACb,EACD,EACW;EAEd,YAAY,MAAU;AAEf,GADA,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,SAAS,EAAE,CAAC,EAC3D,EAAY,kBAAkB,EAAE,UAAU;IAAC;IAAI;IAAS,EAAM;IAAG,EAAE,CAAC;;EAE5E,CAAC;GAGS,UAA2B;CACtC,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,EAAE,OAAI,iBACV,MAAM,EACjB;2DACmD,EAAa;YAEhE;GAAE;GAAI;GAAQ,EACd,EACD,EACW;EAEd,YAAY,MAAU;AAEf,GADA,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,SAAS,EAAE,CAAC,EAC3D,EAAY,kBAAkB,EAAE,UAAU;IAAC;IAAI;IAAS,EAAM;IAAG,EAAE,CAAC;;EAE5E,CAAC;GA8BS,KAAkB,IAA4B,EAAE,KAAK;CAChE,IAAM,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAS;EACd,UAAU;GAAC;GAAI;GAAe;GAAK;EACnC,SAAS,aACM,MAAM,EACjB;;sBAEc,EAAkB;;;YAIhC;GAAE,SAAS,EAAK;GAAS,QAAQ,EAAK;GAAQ,EAC9C,EACD,EACW,mBAAmB;EAElC,CAAC;GAMS,KAAiB,MAA2B;CACvD,IAAM,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAS;EACd,UAAU;GAAC;GAAI;GAAc;GAAG;EAChC,SAAS,YAAY;GACnB,IAAM,IAAO,MAAM,EACjB;;cAEM,EAAkB;;8BAEF,EAAkB;;YAGxC,EAAE,OAAI,EACN,EACD;AACD,OAAI,CAAC,EAAK,cAAe,QAAO;GAChC,IAAM,EAAE,UAAO,GAAG,MAAS,EAAK;AAChC,UAAO;IAAE,GAAG;IAAM,OAAO,GAAO,SAAS,EAAE;IAAE;;EAE/C,SAAS,EAAQ;EAClB,CAAC;GAGS,UAA4B;CACvC,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB;iDACyC,EAAkB;YAE3D,EAAE,UAAO,EACT,EACD,EACW;EAEd,iBAAiB;AACV,KAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,cAAc,EAAE,CAAC;;EAExE,CAAC;GAGS,UAA4B;CACvC,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,EAAE,OAAI,gBACV,MAAM,EACjB;0DACkD,EAAkB;YAEpE;GAAE;GAAI;GAAO,EACb,EACD,EACW;EAEd,YAAY,MAAe;AAEpB,GADA,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,cAAc,EAAE,CAAC,EAChE,EAAY,kBAAkB,EAAE,UAAU;IAAC;IAAI;IAAc,EAAW;IAAG,EAAE,CAAC;;EAEtF,CAAC;GAGS,UAA6B;CACxC,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB;4CACoC,EAAkB;YAEtD,EAAE,OAAI,EACN,EACD,EACW;EAEd,YAAY,MAAe;AAEpB,GADA,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,cAAc,EAAE,CAAC,EAChE,EAAY,kBAAkB,EAAE,UAAU;IAAC;IAAI;IAAc,EAAW;IAAG,EAAE,CAAC;;EAEtF,CAAC;GAGS,UAA6B;CACxC,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB,6EACA,EAAE,OAAI,EACN,EACD,EACW;EAEd,iBAAiB;AACV,KAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,cAAc,EAAE,CAAC;;EAExE,CAAC;GAeS,KAAiB,IAA2B,EAAE,KAAK;CAC9D,IAAM,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAS;EACd,UAAU;GAAC;GAAI;GAAe;GAAK;EACnC,SAAS,aACM,MAAM,EACjB;;;;;;;;sBAQc,EAAkB;;;YAIhC;GACE,SAAS,EAAK;GACd,cAAc,EAAK;GACnB,UAAU,EAAK;GACf,QAAQ,EAAK;GACb,YAAY,EAAK,cAAc;IAAE,OAAO;IAAI,QAAQ;IAAG;GACxD,EACD,EACD,EACW;EAEf,CAAC;GAGS,KAAgB,MAA2B;CACtD,IAAM,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAS;EACd,UAAU;GAAC;GAAI;GAAc;GAAG;EAChC,SAAS,aACM,MAAM,EACjB;;cAEM,EAAkB;cAClB,EAAqB;;;;YAK3B,EAAE,OAAI,EACN,EACD,EACW;EAEd,SAAS,EAAQ;EAClB,CAAC;GAGS,UAA2B;CACtC,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB;gDACwC,EAAkB;YAE1D,EAAE,UAAO,EACT,EACD,EACW;EAEd,iBAAiB;AACV,KAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,cAAc,EAAE,CAAC;;EAExE,CAAC;GAGS,UAA2B;CACtC,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,EAAE,OAAI,gBACV,MAAM,EACjB;yDACiD,EAAkB;YAEnE;GAAE;GAAI;GAAO,EACb,EACD,EACW;EAEd,YAAY,MAAS;AAId,GAHA,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,cAAc,EAAE,CAAC,EAChE,EAAY,kBAAkB,EAAE,UAAU;IAAC;IAAI;IAAc,EAAK;IAAG,EAAE,CAAC,EAExE,EAAY,kBAAkB,EAAE,UAAU;IAAC;IAAI;IAAwB,EAAK;IAAG,EAAE,CAAC;;EAE1F,CAAC;GAUS,UAAqC;CAChD,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB;uDAC+C,EAAqB;YAEpE,EAAE,OAAI,EACN,EACD,EACW;EAEd,YAAY,MAAW;AAIhB,GAHL,EAAY,aAAkC;IAAC;IAAI;IAAc,EAAO;IAAG,GAAG,MAC5E,KAAO;IAAE,GAAG;IAAM,GAAG;IAAQ,CAC9B,EACI,EAAY,kBAAkB,EAAE,UAAU;IAAC;IAAI;IAAc,EAAO;IAAG,EAAE,CAAC;;EAElF,CAAC;GAGS,UAA4B;CACvC,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB,2EACA,EAAE,OAAI,EACN,EACD,EACW;EAEd,iBAAiB;AACV,KAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,cAAc,EAAE,CAAC;;EAExE,CAAC;GAcS,KAAY,IAAsB,EAAE,KAAK;CACpD,IAAM,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAS;EACd,UAAU;GAAC;GAAI;GAAS;GAAK;EAC7B,SAAS,aACM,MAAM,EACjB;;;;sBAIc,EAAY;;;YAI1B;GACE,UAAU,EAAK;GACf,UAAU,EAAK;GACf,UAAU,EAAK;GACf,YAAY,EAAK,cAAc;IAAE,OAAO;IAAI,QAAQ;IAAG;GACxD,EACD,EACD,EACW;EAEf,CAAC;GAMS,KAAW,MAA2B;CACjD,IAAM,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAS;EACd,UAAU;GAAC;GAAI;GAAQ;GAAG;EAC1B,SAAS,YAAY;GACnB,IAAM,IAAO,MAAM,EACjB;;cAEM,EAAY;8BACI,EAAiB;;YAGvC,EAAE,OAAI,EACN,EACD;AACD,OAAI,CAAC,EAAK,QAAS,QAAO;GAC1B,IAAM,EAAE,UAAO,GAAG,MAAS,EAAK;AAChC,UAAO;IAAE,GAAG;IAAM,OAAO,GAAO,SAAS,EAAE;IAAE;;EAE/C,SAAS,EAAQ;EAClB,CAAC;GAGS,KAAqB,IAAsB,EAAE,KAAK;CAC7D,IAAM,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAS;EACd,UAAU;GAAC;GAAI;GAAoB;GAAK;EACxC,SAAS,YAAY;GACnB,IAAM,IAAO,MAAM,EAGjB;;;;sBAIc,EAAY,mBAAmB,EAAiB;;;YAI9D;IACE,UAAU,EAAK;IACf,UAAU,EAAK;IACf,UAAU,EAAK;IACf,YAAY,EAAK,cAAc;KAAE,OAAO;KAAI,QAAQ;KAAG;IACxD,EACD,EACD;AACD,UAAO;IACL,OAAO,EAAK,aAAa,MAAM,KAC5B,EAAE,UAAO,GAAG,SAAY;KAAE,GAAG;KAAM,OAAO,GAAO,SAAS,EAAE;KAAE,EAChE;IACD,UAAU,EAAK,aAAa;IAC7B;;EAEJ,CAAC;GAGS,UAAsB;CACjC,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB;2CACmC,EAAY;YAE/C,EAAE,UAAO,EACT,EACD,EACW;EAEd,iBAAiB;AAEV,GADA,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,QAAQ,EAAE,CAAC,EAC1D,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,mBAAmB,EAAE,CAAC;;EAE7E,CAAC;GAGS,UAAsB;CACjC,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,EAAE,OAAI,gBACV,MAAM,EACjB;oDAC4C,EAAY;YAExD;GAAE;GAAI;GAAO,EACb,EACD,EACW;EAEd,YAAY,MAAS;AAGd,GAFA,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,QAAQ,EAAE,CAAC,EAC1D,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,mBAAmB,EAAE,CAAC,EACrE,EAAY,kBAAkB,EAAE,UAAU;IAAC;IAAI;IAAQ,EAAK;IAAG,EAAE,CAAC;;EAE1E,CAAC;GAGS,UAAuB;CAClC,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB,iEAAiE,EAAY,OAC7E,EAAE,OAAI,EACN,EACD,EACW;EAEd,YAAY,MAAS;AAGd,GAFA,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,QAAQ,EAAE,CAAC,EAC1D,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,mBAAmB,EAAE,CAAC,EACrE,EAAY,kBAAkB,EAAE,UAAU;IAAC;IAAI;IAAQ,EAAK;IAAG,EAAE,CAAC;;EAE1E,CAAC;GAGS,UAAoB;CAC/B,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB,2DAA2D,EAAY,OACvE,EAAE,OAAI,EACN,EACD,EACW;EAEd,YAAY,MAAS;AAGd,GAFA,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,QAAQ,EAAE,CAAC,EAC1D,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,mBAAmB,EAAE,CAAC,EACrE,EAAY,kBAAkB,EAAE,UAAU;IAAC;IAAI;IAAQ,EAAK;IAAG,EAAE,CAAC;;EAE1E,CAAC;GAGS,UAAsB;CACjC,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB,+DAA+D,EAAY,OAC3E,EAAE,OAAI,EACN,EACD,EACW;EAEd,YAAY,MAAS;AAGd,GAFA,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,QAAQ,EAAE,CAAC,EAC1D,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,mBAAmB,EAAE,CAAC,EACrE,EAAY,kBAAkB,EAAE,UAAU;IAAC;IAAI;IAAQ,EAAK;IAAG,EAAE,CAAC;;EAE1E,CAAC;GAGS,UAAoB;CAC/B,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB,2DAA2D,EAAY,OACvE,EAAE,OAAI,EACN,EACD,EACW;EAEd,YAAY,MAAS;AAGd,GAFA,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,QAAQ,EAAE,CAAC,EAC1D,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,mBAAmB,EAAE,CAAC,EACrE,EAAY,kBAAkB,EAAE,UAAU;IAAC;IAAI;IAAQ,EAAK;IAAG,EAAE,CAAC;;EAE1E,CAAC;GAGS,UAAsB;CACjC,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB,+DAA+D,EAAY,OAC3E,EAAE,OAAI,EACN,EACD,EACW;EAEd,YAAY,MAAS;AAGd,GAFA,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,QAAQ,EAAE,CAAC,EAC1D,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,mBAAmB,EAAE,CAAC,EACrE,EAAY,kBAAkB,EAAE,UAAU;IAAC;IAAI;IAAQ,EAAK;IAAG,EAAE,CAAC;;EAE1E,CAAC;GAGS,UAAsB;CACjC,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB,+DACA,EAAE,OAAI,EACN,EACD,EACW;EAEd,iBAAiB;AAEV,GADA,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,QAAQ,EAAE,CAAC,EAC1D,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,mBAAmB,EAAE,CAAC;;EAE7E,CAAC;GAaS,KAAqB,IAA+B,EAAE,KAAK;CACtE,IAAM,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAS;EACd,UAAU;GAAC;GAAI;GAAkB;GAAK;EACtC,SAAS,aACM,MAAM,EACjB;;sBAEc,EAAqB;;;YAInC;GAAE,SAAS,EAAK;GAAS,WAAW,EAAK;GAAW,QAAQ,EAAK;GAAQ,EACzE,EACD,EACW,sBAAsB;EAErC,CAAC;GAMS,KAAoB,MAA2B;CAC1D,IAAM,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAS;EACd,UAAU;GAAC;GAAI;GAAiB;GAAG;EACnC,SAAS,YAAY;GACnB,IAAM,IAAO,MAAM,EACjB;;cAEM,EAAqB;;8BAEL,EAAY;uBACnB,EAA4B;;YAG3C,EAAE,OAAI,EACN,EACD;AACD,OAAI,CAAC,EAAK,iBAAkB,QAAO;GACnC,IAAM,EAAE,UAAO,GAAG,MAAS,EAAK;AAChC,UAAO;IAAE,GAAG;IAAM,OAAO,GAAO,SAAS,EAAE;IAAE;;EAE/C,SAAS,EAAQ;EAClB,CAAC;GAGS,WAA+B;CAC1C,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB;oDAC4C,EAAqB;YAEjE,EAAE,UAAO,EACT,EACD,EACW;EAEd,iBAAiB;AACV,KAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,iBAAiB,EAAE,CAAC;;EAE3E,CAAC;GAGS,UAA+B;CAC1C,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,EAAE,OAAI,gBACV,MAAM,EACjB;;cAEM,EAAqB;;;YAI3B;GAAE;GAAI;GAAO,EACb,EACD,EACW;EAEd,YAAY,MAAW;AAEhB,GADA,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,iBAAiB,EAAE,CAAC,EACnE,EAAY,kBAAkB,EAAE,UAAU;IAAC;IAAI;IAAiB,EAAO;IAAG,EAAE,CAAC;;EAErF,CAAC;GAGS,UAAmC;CAC9C,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,EAAE,OAAI,iBACV,MAAM,EACjB;mEAC2D,EAAqB;YAEhF;GAAE;GAAI;GAAQ,EACd,EACD,EACW;EAEd,YAAY,MAAW;AAEhB,GADA,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,iBAAiB,EAAE,CAAC,EACnE,EAAY,kBAAkB,EAAE,UAAU;IAAC;IAAI;IAAiB,EAAO;IAAG,EAAE,CAAC;;EAErF,CAAC;GAIS,UAA+B;CAC1C,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB,iFACA,EAAE,OAAI,EACN,EACD,EACW;EAEd,iBAAiB;AACV,KAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,iBAAiB,EAAE,CAAC;;EAE3E,CAAC;GAYS,KAAoB,IAAyB,EAAE,KAAK;CAC/D,IAAM,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAS;EACd,UAAU;GAAC;GAAI;GAAY;GAAK;EAChC,SAAS,aACM,MAAM,EACjB;;sBAEc,EAAgB;;;YAI9B;GAAE,UAAU,EAAK;GAAU,QAAQ,EAAK;GAAQ,EAChD,EACD,EACW,qBAAqB;EAEpC,CAAC;GAGS,UAA8B;CACzC,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB;mDAC2C,EAAgB;YAE3D,EAAE,UAAO,EACT,EACD,EACW;EAEd,iBAAiB;AACV,KAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,WAAW,EAAE,CAAC;;EAErE,CAAC;GAuBS,WAA2B;CACtC,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB;0CACkC,EAAgB;YAElD,EAAE,OAAI,EACN,EACD,EACW;EAEd,iBAAiB;AACV,KAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,WAAW,EAAE,CAAC;;EAErE,CAAC;GAGS,WAA8B;CACzC,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB,+EACA,EAAE,OAAI,EACN,EACD,EACW;EAEd,iBAAiB;AACV,KAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,WAAW,EAAE,CAAC;;EAErE,CAAC;GAOS,WAA0B;CACrC,IAAM,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAS;EACd,UAAU,CAAC,GAAI,mBAAmB;EAClC,SAAS,aACM,MAAM,EACjB,iDAAiD,EAAe,OAChE,EAAE,EACF,EACD,EACW;EAEf,CAAC;GA8BS,MAA0B,MAAgC;CACrE,IAAM,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAS;EACd,UAAU;GAAC;GAAI;GAA0B;GAAQ;EACjD,SAAS,aACM,MAAM,EACjB;wDACgD,EAAe;YAE/D,EAAE,YAAS,EACX,EACD,EACW;EAEd,SAAS,EAAQ;EAClB,CAAC;GAGS,WAA8B;CACzC,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB;mDAC2C,EAAe;YAE1D,EAAE,UAAO,EACT,EACD,EACW;EAEd,iBAAiB;AACV,KAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,mBAAmB,EAAE,CAAC;;EAE7E,CAAC;GAQE,IACJ,kFAEW,MAAgB,MAAqB;CAChD,IAAM,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAS;EACd,UAAU;GAAC;GAAI;GAAa;GAAQ;EACpC,SAAS,aACM,MAAM,EAMjB;;;gBAGQ,EAAgB;kCACE,EAAsB;;;;YAKhD,EAAE,YAAS,EACX,EACD,EACW,iBAAiB,MAAM,KAAK,EAAE,YAAS,GAAG,SAAY;GAChE,GAAG;GACH,SAAS,GAAS,SAAS,EAAE;GAC9B,EAAE;EAEN,CAAC;GAGS,WAA0B;CACrC,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB;+CACuC,EAAgB;YAEvD,EAAE,UAAO,EACT,EACD,EACW;EAEd,iBAAiB;AACV,KAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,YAAY,EAAE,CAAC;;EAEtE,CAAC;GAGS,WAA4B;CACvC,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB,6NAKA,EAAE,UAAO,EACT,EACD,EACW;EAEd,YAAY,MAAU;AAGf,GAFA,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,YAAY,EAAE,CAAC,EAC9D,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,WAAW,EAAE,CAAC,EAC7D,EAAY,kBAAkB,EAAE,UAAU;IAAC;IAAI;IAAY,EAAM;IAAW,EAAE,CAAC;;EAEvF,CAAC;GAGS,WAA+B;CAC1C,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB,iFACA,EAAE,OAAI,EACN,EACD,EACW;EAEd,iBAAiB;AAEV,GADA,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,YAAY,EAAE,CAAC,EAC9D,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,WAAW,EAAE,CAAC;;EAErE,CAAC;GAOE,KAAwB,sJAOjB,MAAkB,MAAmC;CAChE,IAAM,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAS;EACd,UAAU;GAAC;GAAI;GAAgB;GAAW;EAC1C,SAAS,EAAQ;EACjB,SAAS,aACM,MAAM,EACjB,sFACA,EAAE,eAAY,EACd,EACD,EACW;EAEf,CAAC;GAGS,UAAkB;CAC7B,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB,+EACA,EAAE,eAAY,EACd,EACD,EACW;EAEd,YAAY,GAAS,MAAe;AAI7B,GAHA,EAAY,kBAAkB,EAAE,UAAU;IAAC;IAAI;IAAgB;IAAW,EAAE,CAAC,EAC7E,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,eAAe,EAAE,CAAC,EACjE,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,eAAe,EAAE,CAAC,EACjE,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,mBAAmB,EAAE,CAAC;;EAE7E,CAAC;GAGS,WAAoB;CAC/B,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB,mFACA,EAAE,eAAY,EACd,EACD,EACW;EAEd,YAAY,GAAS,MAAe;AAI7B,GAHA,EAAY,kBAAkB,EAAE,UAAU;IAAC;IAAI;IAAgB;IAAW,EAAE,CAAC,EAC7E,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,eAAe,EAAE,CAAC,EACjE,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,eAAe,EAAE,CAAC,EACjE,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,mBAAmB,EAAE,CAAC;;EAE7E,CAAC;GAIS,WAAuB;CAClC,IAAM,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAS;EACd,UAAU,CAAC,GAAI,eAAe;EAC9B,SAAS,aACM,MAAM,EACjB;qCAC6B,GAAsB;YAEnD,EAAE,EACF,EACD,EACW,eAAe;EAE9B,CAAC;GAqBS,MAAe,MAA2B;CACrD,IAAM,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAS;EACd,UAAU;GAAC;GAAI;GAAY;GAAG;EAC9B,SAAS,YAAY;GACnB,IAAM,IAAO,MAAM,EAGjB;;cAEM,EAAgB;gCACE,EAAsB;;YAG9C,EAAE,OAAI,EACN,EACD;AACD,OAAI,CAAC,EAAK,YAAa,QAAO;GAC9B,IAAM,EAAE,YAAS,GAAG,MAAS,EAAK;AAClC,UAAO;IAAE,GAAG;IAAM,SAAS,GAAS,SAAS,EAAE;IAAE;;EAEnD,SAAS,EAAQ;EAClB,CAAC;GAGS,WAA0B;CACrC,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB,uEACA,EAAE,OAAI,EACN,EACD,EACW;EAEd,iBAAiB;AAEV,GADA,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,YAAY,EAAE,CAAC,EAC9D,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,WAAW,EAAE,CAAC;;EAErE,CAAC;GAkBS,MAAuB,EAAE,aAAU,IAAM,GAAG,QAAiC;CACxF,IAAM,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAS;EACd,UAAU;GAAC;GAAI;GAAsB;GAAK;EAC1C;EACA,SAAS,aACM,MAAM,EACjB;;sBAEc,EAAkB;;;YAIhC;GACE,OAAO,EAAK;GACZ,YAAY,EAAK,cAAc;IAAE,OAAO;IAAI,QAAQ;IAAG;GACxD,EACD,EACD,EACW;EAEf,CAAC;GAcS,MAAkB,EAAE,aAAU,IAAM,GAAG,QAA4B;CAC9E,IAAM,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAS;EACd,UAAU;GAAC;GAAI;GAAgB;GAAK;EACpC;EACA,SAAS,aACM,MAAM,EACjB;;sBAEc,EAAY;;;YAI1B;GACE,OAAO,EAAK;GACZ,YAAY,EAAK,cAAc;IAAE,OAAO;IAAI,QAAQ;IAAG;GACxD,EACD,EACD,EACW;EAEf,CAAC;GAOS,WAAwB;CACnC,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB,mEAAmE,EAAa,OAChF,EAAE,OAAI,EACN,EACD,EACW;EAEd,YAAY,MAAU;AAEf,GADA,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,SAAS,EAAE,CAAC,EAC3D,EAAY,kBAAkB,EAAE,UAAU;IAAC;IAAI;IAAS,EAAM;IAAG,EAAE,CAAC;;EAE5E,CAAC;GAGS,WAAuB;CAClC,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB,iEAAiE,EAAa,OAC9E,EAAE,OAAI,EACN,EACD,EACW;EAEd,YAAY,MAAU;AAEf,GADA,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,SAAS,EAAE,CAAC,EAC3D,EAAY,kBAAkB,EAAE,UAAU;IAAC;IAAI;IAAS,EAAM;IAAG,EAAE,CAAC;;EAE5E,CAAC;GAGS,WAA+B;CAC1C,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,EAAE,OAAI,gBACV,MAAM,EACjB;6DACqD,EAAqB;YAE1E;GAAE;GAAI;GAAO,EACb,EACD,EACW;EAEd,YAAY,MAAW;AAEhB,GADA,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,iBAAiB,EAAE,CAAC,EACnE,EAAY,kBAAkB,EAAE,UAAU;IAAC;IAAI;IAAiB,EAAO;IAAG,EAAE,CAAC;;EAErF,CAAC;GAGS,WAA4B;CACvC,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB,2EAA2E,EAAkB,OAC7F,EAAE,OAAI,EACN,EACD,EACW;EAEd,YAAY,MAAS;AAEd,GADA,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,cAAc,EAAE,CAAC,EAChE,EAAY,kBAAkB,EAAE,UAAU;IAAC;IAAI;IAAc,EAAK;IAAG,EAAE,CAAC;;EAEhF,CAAC;GAGS,WAA8B;CACzC,IAAM,IAAc,GAAgB,EAC9B,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB,+EAA+E,EAAkB,OACjG,EAAE,OAAI,EACN,EACD,EACW;EAEd,YAAY,MAAS;AAEd,GADA,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,cAAc,EAAE,CAAC,EAChE,EAAY,kBAAkB,EAAE,UAAU;IAAC;IAAI;IAAc,EAAK;IAAG,EAAE,CAAC;;EAEhF,CAAC"}
@@ -85,10 +85,13 @@ async function p(e, t, n = a.items, r) {
85
85
  name: b?.name ?? e.name
86
86
  };
87
87
  }
88
- async function m(e, t, n = a.items, r) {
88
+ async function m(e, t, n = a.items) {
89
+ return p(e, t, n);
90
+ }
91
+ async function h(e, t, n = a.items, r) {
89
92
  return p(e, t, n, r);
90
93
  }
91
- function h(n) {
94
+ function g(n) {
92
95
  let { apiGatewayUrl: r } = e();
93
96
  return t({
94
97
  queryKey: [
@@ -106,6 +109,6 @@ function h(n) {
106
109
  });
107
110
  }
108
111
  //#endregion
109
- export { a as COO_FILE_FOLDERS, m as uploadImageToFilesWithProgress, h as useFileUrl };
112
+ export { a as COO_FILE_FOLDERS, m as uploadImageToFiles, h as uploadImageToFilesWithProgress, g as useFileUrl };
110
113
 
111
114
  //# sourceMappingURL=useFiles.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useFiles.js","names":[],"sources":["../../../src/coolandlovely/hooks/useFiles.ts"],"sourcesContent":["/**\n * File hooks — image upload + display via wspace-files-svc (NO duplication).\n * @module coolandlovely/hooks\n *\n * CoolAndLovely never stores blobs. Brand logos/covers, collection covers,\n * style-item photos, look photos, wardrobe photos and lookbook covers are\n * wspace-files `File` records referenced by id (the coo* inputs take *FileId;\n * the coo* types expose logo/cover/image: File resolved via federation).\n *\n * Upload uses the SAME graphqlFetch transport as every other coo* call — NOT\n * Apollo — driving the wspace-files 3-step presigned flow directly:\n * ensureFolderByPath -> initiateUpload -> HTTP PUT -> completeUpload\n * Display resolves a File id to a short-lived presigned URL via\n * getFileDownloadUrl.\n *\n * Two fleet gotchas are handled here:\n * (a) `fileSize` is REQUIRED on completeUpload even though this MFE's generated\n * `CompleteUploadInput` is stale and omits it. Because we send a hand-written\n * query with `Record<string, unknown>` variables (not typed against the\n * generated input) we simply include it and it works at runtime.\n * (b) `getFileDownloadUrl(expiresIn)` must be <= 604800 (S3 7-day cap → 500).\n * We use 21600 (6h); do NOT raise it.\n */\n\nimport { useQuery } from '@tanstack/react-query';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\nimport { clearGraphqlFetchResponseCache } from '@burdenoff/fe-libs/shared/graphql/fetch';\n\nimport { useCoolAndLovely } from '../context';\n\n/**\n * 6 hours. getFileDownloadUrl rejects TTLs > 604800 (S3 7-day cap → 500); the\n * safe fleet ceiling is 21600. Do NOT raise this.\n */\nconst DOWNLOAD_URL_TTL_SECONDS = 21_600;\n\n/** Per-entity folders in wspace-files. */\nexport const COO_FILE_FOLDERS = {\n brands: '/CoolAndLovely/Brands',\n collections: '/CoolAndLovely/Collections',\n items: '/CoolAndLovely/Items',\n looks: '/CoolAndLovely/Looks',\n wardrobe: '/CoolAndLovely/Wardrobe',\n lookbooks: '/CoolAndLovely/Lookbooks',\n} as const;\n\nexport type CooFileFolder = (typeof COO_FILE_FOLDERS)[keyof typeof COO_FILE_FOLDERS];\n\nexport interface UploadedImage {\n id: string;\n url: string;\n name: string;\n}\n\n/** Thin wrapper over the workspace gateway using the MFE's proven transport. */\nasync function filesFetch<TData>(\n query: string,\n variables: Record<string, unknown>,\n baseUrl?: string\n): Promise<TData> {\n const response = await graphqlFetch<TData>({\n gateway: 'workspace',\n baseUrl,\n query,\n variables,\n workspaceToken: true,\n });\n if (response.errors?.length) {\n throw new Error(response.errors[0]?.message ?? 'Files request failed');\n }\n if (!response.data) {\n throw new Error('Files response did not include data');\n }\n // Drop fe-libs' ~15s query response cache after a mutation so a follow-up\n // getFileDownloadUrl reads fresh (mirrors coolQuery in useCoolAndLovelyApi).\n if (/^\\s*mutation\\b/.test(query)) {\n clearGraphqlFetchResponseCache();\n }\n return response.data;\n}\n\nconst ENSURE_FOLDER = `\n mutation CooEnsureFolder($path: String!) {\n ensureFolderByPath(path: $path) { id }\n }\n`;\n\nconst INITIATE_UPLOAD = `\n mutation CooInitiateUpload($input: InitiateUploadInput!) {\n initiateUpload(input: $input) {\n uploadUrl\n session { id }\n }\n }\n`;\n\nconst COMPLETE_UPLOAD = `\n mutation CooCompleteUpload($input: CompleteUploadInput!) {\n completeUpload(input: $input) {\n fileId\n file { id name }\n }\n }\n`;\n\nconst GET_FILE_DOWNLOAD_URL = `\n query CooGetFileDownloadUrl($id: ID!, $expiresIn: Int) {\n getFileDownloadUrl(id: $id, expiresIn: $expiresIn)\n }\n`;\n\nfunction fileExtension(name: string, mimeType: string): string {\n const dot = name.lastIndexOf('.');\n if (dot > -1 && dot < name.length - 1) return name.slice(dot + 1).toLowerCase();\n return (mimeType.split('/')[1] ?? 'bin').toLowerCase();\n}\n\n/** Upload progress emitted by {@link uploadImageToFilesWithProgress}. */\nexport interface UploadProgress {\n /** Bytes transferred so far. */\n loaded: number;\n /** Total bytes to transfer. */\n total: number;\n /** Rounded percentage complete, 0–100. */\n pct: number;\n}\n\n/**\n * PUT the bytes straight to storage via XMLHttpRequest so `upload.onprogress`\n * can surface a real progress bar (the presigned upload URL points at object\n * storage, so a plain PUT is all that is needed — no auth header). Content-Type\n * must match what was sent to `initiateUpload`.\n */\nfunction putWithProgress(\n uploadUrl: string,\n file: File,\n mimeType: string,\n onProgress?: (progress: UploadProgress) => void\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n xhr.open('PUT', uploadUrl, true);\n xhr.setRequestHeader('Content-Type', mimeType);\n if (onProgress) {\n xhr.upload.onprogress = (event: ProgressEvent) => {\n const total = event.lengthComputable ? event.total : file.size;\n const loaded = Math.min(event.loaded, total);\n const pct = total > 0 ? Math.round((loaded / total) * 100) : 0;\n onProgress({ loaded, total, pct });\n };\n }\n xhr.onload = () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n onProgress?.({ loaded: file.size, total: file.size, pct: 100 });\n resolve();\n } else {\n reject(new Error(`Upload to storage failed (${xhr.status}).`));\n }\n };\n xhr.onerror = () => reject(new Error('Upload to storage failed — a network error occurred.'));\n xhr.onabort = () => reject(new Error('Upload was cancelled.'));\n xhr.send(file);\n });\n}\n\n/**\n * The full presigned upload flow (ensureFolder -> initiateUpload -> PUT ->\n * completeUpload -> download URL). Shared by both public upload helpers; the\n * PUT step reports progress when `onProgress` is supplied.\n */\nasync function runUpload(\n file: File,\n baseUrl?: string,\n folderPath: string = COO_FILE_FOLDERS.items,\n onProgress?: (progress: UploadProgress) => void\n): Promise<UploadedImage> {\n const mimeType = file.type || 'application/octet-stream';\n const fileSize = String(file.size); // BigInt scalar — serialize as string.\n\n // 1. Resolve (or create) the destination folder. Best-effort: fall back to\n // the files root (folderId is optional on both initiate + complete).\n let folderId: string | undefined;\n try {\n const folder = await filesFetch<{ ensureFolderByPath?: { id: string } | null }>(\n ENSURE_FOLDER,\n { path: folderPath },\n baseUrl\n );\n folderId = folder.ensureFolderByPath?.id ?? undefined;\n } catch {\n folderId = undefined;\n }\n\n // 2. Open a presigned upload session.\n const initiated = await filesFetch<{\n initiateUpload?: { uploadUrl?: string | null; session: { id: string } } | null;\n }>(\n INITIATE_UPLOAD,\n {\n input: {\n fileName: file.name,\n extension: fileExtension(file.name, mimeType),\n fileSize, // required, BigInt-as-string\n mimeType,\n ...(folderId ? { folderId } : {}),\n },\n },\n baseUrl\n );\n const uploadUrl = initiated.initiateUpload?.uploadUrl;\n const sessionId = initiated.initiateUpload?.session.id;\n if (!uploadUrl || !sessionId) {\n throw new Error('The files service did not return an upload URL.');\n }\n\n // 3. PUT the bytes straight to storage (XHR → progress). Content-Type must\n // match initiateUpload.\n await putWithProgress(uploadUrl, file, mimeType, onProgress);\n\n // 4. Finalize — creates the File record. fileSize is REQUIRED here even though\n // the MFE's generated CompleteUploadInput is stale and omits it.\n const completed = await filesFetch<{\n completeUpload?: { fileId: string; file: { id: string; name: string } } | null;\n }>(\n COMPLETE_UPLOAD,\n {\n input: {\n sessionId,\n fileSize, // <-- stale-type gotcha: the live schema requires this\n ...(folderId ? { folderId } : {}),\n },\n },\n baseUrl\n );\n const record = completed.completeUpload?.file;\n const newId = completed.completeUpload?.fileId ?? record?.id;\n if (!newId) {\n throw new Error('The upload could not be finalized.');\n }\n\n // 5. Best-effort presigned URL for immediate preview.\n let url = '';\n try {\n const urlData = await filesFetch<{ getFileDownloadUrl?: string | null }>(\n GET_FILE_DOWNLOAD_URL,\n { id: newId, expiresIn: DOWNLOAD_URL_TTL_SECONDS },\n baseUrl\n );\n url = urlData.getFileDownloadUrl ?? '';\n } catch {\n url = '';\n }\n\n return { id: newId, url, name: record?.name ?? file.name };\n}\n\n/**\n * Upload an image to wspace-files-svc and return its id + a presigned URL. The\n * caller persists `id` (e.g. cooUpdateBrand({ logoFileId })); `url` is for an\n * immediate preview. `baseUrl` is the shell's apiGatewayUrl.\n */\nexport async function uploadImageToFiles(\n file: File,\n baseUrl?: string,\n folderPath: string = COO_FILE_FOLDERS.items\n): Promise<UploadedImage> {\n return runUpload(file, baseUrl, folderPath);\n}\n\n/**\n * Same as {@link uploadImageToFiles} but reports transfer progress via\n * `onProgress` (XHR `upload.onprogress`) so callers can render a live progress\n * bar. `baseUrl` is the shell's apiGatewayUrl.\n */\nexport async function uploadImageToFilesWithProgress(\n file: File,\n baseUrl?: string,\n folderPath: string = COO_FILE_FOLDERS.items,\n onProgress?: (progress: UploadProgress) => void\n): Promise<UploadedImage> {\n return runUpload(file, baseUrl, folderPath, onProgress);\n}\n\n/** Resolve a wspace-files File id to a presigned URL for display. */\nexport function useFileUrl(fileId?: string | null) {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: ['coolandlovely', 'file-url', fileId ?? ''],\n enabled: Boolean(fileId),\n staleTime: 20 * 60 * 1000, // refetch well inside the 6h TTL\n retry: 1,\n queryFn: async () => {\n const data = await filesFetch<{ getFileDownloadUrl?: string | null }>(\n GET_FILE_DOWNLOAD_URL,\n { id: fileId, expiresIn: DOWNLOAD_URL_TTL_SECONDS },\n apiGatewayUrl\n );\n return data.getFileDownloadUrl ?? null;\n },\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useFiles.js","names":[],"sources":["../../../src/coolandlovely/hooks/useFiles.ts"],"sourcesContent":["/**\n * File hooks — image upload + display via wspace-files-svc (NO duplication).\n * @module coolandlovely/hooks\n *\n * CoolAndLovely never stores blobs. Brand logos/covers, collection covers,\n * style-item photos, look photos, wardrobe photos and lookbook covers are\n * wspace-files `File` records referenced by id (the coo* inputs take *FileId;\n * the coo* types expose logo/cover/image: File resolved via federation).\n *\n * Upload uses the SAME graphqlFetch transport as every other coo* call — NOT\n * Apollo — driving the wspace-files 3-step presigned flow directly:\n * ensureFolderByPath -> initiateUpload -> HTTP PUT -> completeUpload\n * Display resolves a File id to a short-lived presigned URL via\n * getFileDownloadUrl.\n *\n * Two fleet gotchas are handled here:\n * (a) `fileSize` is REQUIRED on completeUpload even though this MFE's generated\n * `CompleteUploadInput` is stale and omits it. Because we send a hand-written\n * query with `Record<string, unknown>` variables (not typed against the\n * generated input) we simply include it and it works at runtime.\n * (b) `getFileDownloadUrl(expiresIn)` must be <= 604800 (S3 7-day cap → 500).\n * We use 21600 (6h); do NOT raise it.\n */\n\nimport { useQuery } from '@tanstack/react-query';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\nimport { clearGraphqlFetchResponseCache } from '@burdenoff/fe-libs/shared/graphql/fetch';\n\nimport { useCoolAndLovely } from '../context';\n\n/**\n * 6 hours. getFileDownloadUrl rejects TTLs > 604800 (S3 7-day cap → 500); the\n * safe fleet ceiling is 21600. Do NOT raise this.\n */\nconst DOWNLOAD_URL_TTL_SECONDS = 21_600;\n\n/** Per-entity folders in wspace-files. */\nexport const COO_FILE_FOLDERS = {\n brands: '/CoolAndLovely/Brands',\n collections: '/CoolAndLovely/Collections',\n items: '/CoolAndLovely/Items',\n looks: '/CoolAndLovely/Looks',\n wardrobe: '/CoolAndLovely/Wardrobe',\n lookbooks: '/CoolAndLovely/Lookbooks',\n} as const;\n\nexport type CooFileFolder = (typeof COO_FILE_FOLDERS)[keyof typeof COO_FILE_FOLDERS];\n\nexport interface UploadedImage {\n id: string;\n url: string;\n name: string;\n}\n\n/** Thin wrapper over the workspace gateway using the MFE's proven transport. */\nasync function filesFetch<TData>(\n query: string,\n variables: Record<string, unknown>,\n baseUrl?: string\n): Promise<TData> {\n const response = await graphqlFetch<TData>({\n gateway: 'workspace',\n baseUrl,\n query,\n variables,\n workspaceToken: true,\n });\n if (response.errors?.length) {\n throw new Error(response.errors[0]?.message ?? 'Files request failed');\n }\n if (!response.data) {\n throw new Error('Files response did not include data');\n }\n // Drop fe-libs' ~15s query response cache after a mutation so a follow-up\n // getFileDownloadUrl reads fresh (mirrors coolQuery in useCoolAndLovelyApi).\n if (/^\\s*mutation\\b/.test(query)) {\n clearGraphqlFetchResponseCache();\n }\n return response.data;\n}\n\nconst ENSURE_FOLDER = `\n mutation CooEnsureFolder($path: String!) {\n ensureFolderByPath(path: $path) { id }\n }\n`;\n\nconst INITIATE_UPLOAD = `\n mutation CooInitiateUpload($input: InitiateUploadInput!) {\n initiateUpload(input: $input) {\n uploadUrl\n session { id }\n }\n }\n`;\n\nconst COMPLETE_UPLOAD = `\n mutation CooCompleteUpload($input: CompleteUploadInput!) {\n completeUpload(input: $input) {\n fileId\n file { id name }\n }\n }\n`;\n\nconst GET_FILE_DOWNLOAD_URL = `\n query CooGetFileDownloadUrl($id: ID!, $expiresIn: Int) {\n getFileDownloadUrl(id: $id, expiresIn: $expiresIn)\n }\n`;\n\nfunction fileExtension(name: string, mimeType: string): string {\n const dot = name.lastIndexOf('.');\n if (dot > -1 && dot < name.length - 1) return name.slice(dot + 1).toLowerCase();\n return (mimeType.split('/')[1] ?? 'bin').toLowerCase();\n}\n\n/** Upload progress emitted by {@link uploadImageToFilesWithProgress}. */\nexport interface UploadProgress {\n /** Bytes transferred so far. */\n loaded: number;\n /** Total bytes to transfer. */\n total: number;\n /** Rounded percentage complete, 0–100. */\n pct: number;\n}\n\n/**\n * PUT the bytes straight to storage via XMLHttpRequest so `upload.onprogress`\n * can surface a real progress bar (the presigned upload URL points at object\n * storage, so a plain PUT is all that is needed — no auth header). Content-Type\n * must match what was sent to `initiateUpload`.\n */\nfunction putWithProgress(\n uploadUrl: string,\n file: File,\n mimeType: string,\n onProgress?: (progress: UploadProgress) => void\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n xhr.open('PUT', uploadUrl, true);\n xhr.setRequestHeader('Content-Type', mimeType);\n if (onProgress) {\n xhr.upload.onprogress = (event: ProgressEvent) => {\n const total = event.lengthComputable ? event.total : file.size;\n const loaded = Math.min(event.loaded, total);\n const pct = total > 0 ? Math.round((loaded / total) * 100) : 0;\n onProgress({ loaded, total, pct });\n };\n }\n xhr.onload = () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n onProgress?.({ loaded: file.size, total: file.size, pct: 100 });\n resolve();\n } else {\n reject(new Error(`Upload to storage failed (${xhr.status}).`));\n }\n };\n xhr.onerror = () => reject(new Error('Upload to storage failed — a network error occurred.'));\n xhr.onabort = () => reject(new Error('Upload was cancelled.'));\n xhr.send(file);\n });\n}\n\n/**\n * The full presigned upload flow (ensureFolder -> initiateUpload -> PUT ->\n * completeUpload -> download URL). Shared by both public upload helpers; the\n * PUT step reports progress when `onProgress` is supplied.\n */\nasync function runUpload(\n file: File,\n baseUrl?: string,\n folderPath: string = COO_FILE_FOLDERS.items,\n onProgress?: (progress: UploadProgress) => void\n): Promise<UploadedImage> {\n const mimeType = file.type || 'application/octet-stream';\n const fileSize = String(file.size); // BigInt scalar — serialize as string.\n\n // 1. Resolve (or create) the destination folder. Best-effort: fall back to\n // the files root (folderId is optional on both initiate + complete).\n let folderId: string | undefined;\n try {\n const folder = await filesFetch<{ ensureFolderByPath?: { id: string } | null }>(\n ENSURE_FOLDER,\n { path: folderPath },\n baseUrl\n );\n folderId = folder.ensureFolderByPath?.id ?? undefined;\n } catch {\n folderId = undefined;\n }\n\n // 2. Open a presigned upload session.\n const initiated = await filesFetch<{\n initiateUpload?: { uploadUrl?: string | null; session: { id: string } } | null;\n }>(\n INITIATE_UPLOAD,\n {\n input: {\n fileName: file.name,\n extension: fileExtension(file.name, mimeType),\n fileSize, // required, BigInt-as-string\n mimeType,\n ...(folderId ? { folderId } : {}),\n },\n },\n baseUrl\n );\n const uploadUrl = initiated.initiateUpload?.uploadUrl;\n const sessionId = initiated.initiateUpload?.session.id;\n if (!uploadUrl || !sessionId) {\n throw new Error('The files service did not return an upload URL.');\n }\n\n // 3. PUT the bytes straight to storage (XHR → progress). Content-Type must\n // match initiateUpload.\n await putWithProgress(uploadUrl, file, mimeType, onProgress);\n\n // 4. Finalize — creates the File record. fileSize is REQUIRED here even though\n // the MFE's generated CompleteUploadInput is stale and omits it.\n const completed = await filesFetch<{\n completeUpload?: { fileId: string; file: { id: string; name: string } } | null;\n }>(\n COMPLETE_UPLOAD,\n {\n input: {\n sessionId,\n fileSize, // <-- stale-type gotcha: the live schema requires this\n ...(folderId ? { folderId } : {}),\n },\n },\n baseUrl\n );\n const record = completed.completeUpload?.file;\n const newId = completed.completeUpload?.fileId ?? record?.id;\n if (!newId) {\n throw new Error('The upload could not be finalized.');\n }\n\n // 5. Best-effort presigned URL for immediate preview.\n let url = '';\n try {\n const urlData = await filesFetch<{ getFileDownloadUrl?: string | null }>(\n GET_FILE_DOWNLOAD_URL,\n { id: newId, expiresIn: DOWNLOAD_URL_TTL_SECONDS },\n baseUrl\n );\n url = urlData.getFileDownloadUrl ?? '';\n } catch {\n url = '';\n }\n\n return { id: newId, url, name: record?.name ?? file.name };\n}\n\n/**\n * Upload an image to wspace-files-svc and return its id + a presigned URL. The\n * caller persists `id` (e.g. cooUpdateBrand({ logoFileId })); `url` is for an\n * immediate preview. `baseUrl` is the shell's apiGatewayUrl.\n */\nexport async function uploadImageToFiles(\n file: File,\n baseUrl?: string,\n folderPath: string = COO_FILE_FOLDERS.items\n): Promise<UploadedImage> {\n return runUpload(file, baseUrl, folderPath);\n}\n\n/**\n * Same as {@link uploadImageToFiles} but reports transfer progress via\n * `onProgress` (XHR `upload.onprogress`) so callers can render a live progress\n * bar. `baseUrl` is the shell's apiGatewayUrl.\n */\nexport async function uploadImageToFilesWithProgress(\n file: File,\n baseUrl?: string,\n folderPath: string = COO_FILE_FOLDERS.items,\n onProgress?: (progress: UploadProgress) => void\n): Promise<UploadedImage> {\n return runUpload(file, baseUrl, folderPath, onProgress);\n}\n\n/** Resolve a wspace-files File id to a presigned URL for display. */\nexport function useFileUrl(fileId?: string | null) {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: ['coolandlovely', 'file-url', fileId ?? ''],\n enabled: Boolean(fileId),\n staleTime: 20 * 60 * 1000, // refetch well inside the 6h TTL\n retry: 1,\n queryFn: async () => {\n const data = await filesFetch<{ getFileDownloadUrl?: string | null }>(\n GET_FILE_DOWNLOAD_URL,\n { id: fileId, expiresIn: DOWNLOAD_URL_TTL_SECONDS },\n apiGatewayUrl\n );\n return data.getFileDownloadUrl ?? null;\n },\n });\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"BrandsListPage.d.ts","sourceRoot":"","sources":["../../../../src/coolandlovely/pages/brands/BrandsListPage.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAuBH,wBAAgB,cAAc,gCAuJ7B"}
1
+ {"version":3,"file":"BrandsListPage.d.ts","sourceRoot":"","sources":["../../../../src/coolandlovely/pages/brands/BrandsListPage.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAuBH,wBAAgB,cAAc,gCAiK7B"}