@dropins/storefront-company-switcher 1.2.1 → 1.3.0-beta.0
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.
- package/CHANGELOG.md +42 -9
- package/api/customerCompanyContext/customerCompanyContext.d.ts +36 -1
- package/api/customerCompanyContext/graphql/catalogViewContext.graphql.d.ts +25 -0
- package/api/index.d.ts +1 -0
- package/api/setCatalogViewHeaders/index.d.ts +17 -0
- package/api/setCatalogViewHeaders/setCatalogViewHeaders.d.ts +106 -0
- package/api.js +14 -5
- package/api.js.map +1 -1
- package/containers/CompanySwitcher/CompanySwitcher.d.ts +1 -1
- package/containers/CompanySwitcher.js.map +1 -1
- package/package.json +1 -1
- package/types/company.d.ts +11 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @dropins/storefront-company-switcher
|
|
2
2
|
|
|
3
|
+
## 1.3.0-beta.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 6127763: Wire Adobe Commerce catalog-view context into the company-switcher
|
|
8
|
+
dropin. On initialize and company switch, the dropin fetches the
|
|
9
|
+
company-scoped catalog view and stamps `AC-View-Id` and
|
|
10
|
+
`AC-Catalog-View-Access-Token` onto shared GraphQL requests, resetting to the
|
|
11
|
+
configured default view on clear/logout.
|
|
12
|
+
|
|
3
13
|
## 1.2.1
|
|
4
14
|
|
|
5
15
|
### Patch Changes
|
|
@@ -23,12 +33,20 @@
|
|
|
23
33
|
|
|
24
34
|
### Minor Changes
|
|
25
35
|
|
|
26
|
-
- 3fbf7de: Add optional `size` prop on `CompanySwitcher` (and `useCompanyData`)
|
|
36
|
+
- 3fbf7de: Add optional `size` prop on `CompanySwitcher` (and `useCompanyData`)
|
|
37
|
+
to control GraphQL `customer.companies` `pageSize`, defaulting to 100 instead
|
|
38
|
+
of the API’s typical cap of 20. `getCustomerCompanyInfo` accepts `{ size }`
|
|
39
|
+
and caches per page size. Restore `CustomerFragment` for extensibility;
|
|
40
|
+
`GET_CUSTOMER_COMPANIES` uses operation variable `$pageSize`.
|
|
27
41
|
- 4860a42: Migrate to Node.js 24 LTS
|
|
28
42
|
|
|
29
|
-
Minimum required Node.js version is now 24. Updated engines.node from >=20
|
|
43
|
+
Minimum required Node.js version is now 24. Updated engines.node from >=20
|
|
44
|
+
to >=24.
|
|
30
45
|
|
|
31
|
-
- 46ca833: Removed the `engines.node` constraint from `package.json`. This
|
|
46
|
+
- 46ca833: Removed the `engines.node` constraint from `package.json`. This
|
|
47
|
+
package targets browser environments exclusively and does not depend on a
|
|
48
|
+
specific Node.js runtime version. The package is now built and distributed
|
|
49
|
+
using Node.js 22 LTS.
|
|
32
50
|
|
|
33
51
|
### Patch Changes
|
|
34
52
|
|
|
@@ -51,24 +69,35 @@
|
|
|
51
69
|
|
|
52
70
|
### Minor Changes
|
|
53
71
|
|
|
54
|
-
- 46ca833: Removed the `engines.node` constraint from `package.json`. This
|
|
72
|
+
- 46ca833: Removed the `engines.node` constraint from `package.json`. This
|
|
73
|
+
package targets browser environments exclusively and does not depend on a
|
|
74
|
+
specific Node.js runtime version. The package is now built and distributed
|
|
75
|
+
using Node.js 22 LTS.
|
|
55
76
|
|
|
56
77
|
## 1.2.0-beta.0
|
|
57
78
|
|
|
58
79
|
### Minor Changes
|
|
59
80
|
|
|
60
|
-
- 3fbf7de: Add optional `size` prop on `CompanySwitcher` (and `useCompanyData`)
|
|
81
|
+
- 3fbf7de: Add optional `size` prop on `CompanySwitcher` (and `useCompanyData`)
|
|
82
|
+
to control GraphQL `customer.companies` `pageSize`, defaulting to 100 instead
|
|
83
|
+
of the API’s typical cap of 20. `getCustomerCompanyInfo` accepts `{ size }`
|
|
84
|
+
and caches per page size. Restore `CustomerFragment` for extensibility;
|
|
85
|
+
`GET_CUSTOMER_COMPANIES` uses operation variable `$pageSize`.
|
|
61
86
|
|
|
62
87
|
## 1.1.1
|
|
63
88
|
|
|
64
89
|
### Patch Changes
|
|
65
90
|
|
|
66
91
|
- 0499d70: Bump "@adobe-commerce/elsie" from 1.8.0-beta0 to 1.8.0-beta1
|
|
67
|
-
- 1de9f29: Add Changesets-based release automation with branch-aware workflows
|
|
92
|
+
- 1de9f29: Add Changesets-based release automation with branch-aware workflows
|
|
93
|
+
(alpha/beta/stable), PR changeset validation, and contributor helper scripts.
|
|
68
94
|
- d9d1c6a: Bump `@adobe-commerce/elsie` from 1.7.0 to 1.8.0
|
|
69
95
|
- 7343c2e: fix: merge user-provided langDefinitions in Provider
|
|
70
96
|
|
|
71
|
-
The Provider now imports `config` and uses `deepmerge` to merge user-provided
|
|
97
|
+
The Provider now imports `config` and uses `deepmerge` to merge user-provided
|
|
98
|
+
`langDefinitions` with the drop-in's bundled defaults before passing them to
|
|
99
|
+
`UIProvider`. This enables label/placeholder overrides via the initializer
|
|
100
|
+
API.
|
|
72
101
|
|
|
73
102
|
- d2368e4: Bump adobe-commerce/elsie from 1.8.0-beta.1 to 1.8.0
|
|
74
103
|
|
|
@@ -94,7 +123,11 @@
|
|
|
94
123
|
|
|
95
124
|
### Patch Changes
|
|
96
125
|
|
|
97
|
-
- 1de9f29: Add Changesets-based release automation with branch-aware workflows
|
|
126
|
+
- 1de9f29: Add Changesets-based release automation with branch-aware workflows
|
|
127
|
+
(alpha/beta/stable), PR changeset validation, and contributor helper scripts.
|
|
98
128
|
- 7343c2e: fix: merge user-provided langDefinitions in Provider
|
|
99
129
|
|
|
100
|
-
The Provider now imports `config` and uses `deepmerge` to merge user-provided
|
|
130
|
+
The Provider now imports `config` and uses `deepmerge` to merge user-provided
|
|
131
|
+
`langDefinitions` with the drop-in's bundled defaults before passing them to
|
|
132
|
+
`UIProvider`. This enables label/placeholder overrides via the initializer
|
|
133
|
+
API.
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* is strictly forbidden unless prior written permission is obtained
|
|
15
15
|
* from Adobe.
|
|
16
16
|
*******************************************************************/
|
|
17
|
-
import type { CustomerCompanyInfo } from '../../types/company';
|
|
17
|
+
import type { CatalogViewContext, CustomerCompanyInfo } from '../../types/company';
|
|
18
18
|
export declare class CustomerCompanyContext {
|
|
19
19
|
private static instance;
|
|
20
20
|
private readonly EMPTY_CUSTOMER_COMPANY_CONTEXT;
|
|
@@ -43,6 +43,40 @@ export declare class CustomerCompanyContext {
|
|
|
43
43
|
* @throws Will not throw errors - returns null on failure
|
|
44
44
|
*/
|
|
45
45
|
updateCustomerGroup(): Promise<string | null>;
|
|
46
|
+
/**
|
|
47
|
+
* Fetches the company-scoped catalog view context in an ISOLATED GraphQL
|
|
48
|
+
* operation, deliberately separate from the shared company query.
|
|
49
|
+
*
|
|
50
|
+
* Robust against cases where feature is not yet deployed on target backend:
|
|
51
|
+
* an unknown-field schema error is treated as the expected "feature absent"
|
|
52
|
+
* (deploy-skew) case and skipped silently, while a real/transient error is
|
|
53
|
+
* surfaced loudly (still returning null, as there is no UI to render).
|
|
54
|
+
*
|
|
55
|
+
* @returns Promise resolving to the catalog view context, or null on any failure
|
|
56
|
+
* @throws Will not throw errors - returns null on failure
|
|
57
|
+
*/
|
|
58
|
+
getCatalogViewContext(): Promise<CatalogViewContext | null>;
|
|
59
|
+
/**
|
|
60
|
+
* Decides whether a GraphQL error array represents the expected "feature not
|
|
61
|
+
* deployed" case — an unknown-field SCHEMA VALIDATION error for
|
|
62
|
+
* `catalogViewContext` — versus a real/transient error that must not be
|
|
63
|
+
* silently swallowed as deploy-skew.
|
|
64
|
+
*
|
|
65
|
+
* The unknown-field case is a pre-execution validation error, so it carries
|
|
66
|
+
* NO Magento runtime `extensions.category` (`graphql-*`); its only signal is
|
|
67
|
+
* the webonyx-generated English message `Cannot query field
|
|
68
|
+
* "catalogViewContext" ...` (or, via API Mesh, a `GRAPHQL_VALIDATION_FAILED`
|
|
69
|
+
* code). We treat the batch as "feature absent" only when NO error carries a
|
|
70
|
+
* real Magento runtime category AND at least one error matches the
|
|
71
|
+
* unknown-field signature for our field.
|
|
72
|
+
*
|
|
73
|
+
* `extensions` is typed as non-optional by the fetch-graphql client but is
|
|
74
|
+
* `undefined` for validation errors, so every access is null-guarded.
|
|
75
|
+
*
|
|
76
|
+
* NOTE: an API Mesh in front of Commerce can rewrite both the message and the
|
|
77
|
+
* extensions, so this remains a best-effort heuristic, not a hard contract.
|
|
78
|
+
*/
|
|
79
|
+
private isCatalogViewFieldAbsent;
|
|
46
80
|
/**
|
|
47
81
|
* Fetches customer company information including the current company and all available companies
|
|
48
82
|
*
|
|
@@ -53,3 +87,4 @@ export declare class CustomerCompanyContext {
|
|
|
53
87
|
}
|
|
54
88
|
export declare const getCustomerCompanyInfo: (pageSize?: number) => Promise<CustomerCompanyInfo>;
|
|
55
89
|
export declare const updateCustomerGroup: () => Promise<string | null>;
|
|
90
|
+
export declare const getCatalogViewContext: () => Promise<CatalogViewContext | null>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/********************************************************************
|
|
2
|
+
* ADOBE CONFIDENTIAL
|
|
3
|
+
* __________________
|
|
4
|
+
*
|
|
5
|
+
* Copyright 2026 Adobe
|
|
6
|
+
* All Rights Reserved.
|
|
7
|
+
*
|
|
8
|
+
* NOTICE: All information contained herein is, and remains
|
|
9
|
+
* the property of Adobe and its suppliers, if any. The intellectual
|
|
10
|
+
* and technical concepts contained herein are proprietary to Adobe
|
|
11
|
+
* and its suppliers and are protected by all applicable intellectual
|
|
12
|
+
* property laws, including trade secret and copyright laws.
|
|
13
|
+
* Dissemination of this information or reproduction of this material
|
|
14
|
+
* is strictly forbidden unless prior written permission is obtained
|
|
15
|
+
* from Adobe.
|
|
16
|
+
*******************************************************************/
|
|
17
|
+
/**
|
|
18
|
+
* Isolated query for the company-scoped catalog view context.
|
|
19
|
+
*
|
|
20
|
+
* This is intentionally a self-contained operation (NOT part of
|
|
21
|
+
* COMPANY_FRAGMENT). The backend that serves `Company.catalogViewContext` may
|
|
22
|
+
* roll out independently from this storefront, so this field may be queried
|
|
23
|
+
* against an endpoint whose schema does not yet declare it.
|
|
24
|
+
*/
|
|
25
|
+
export declare const GET_CATALOG_VIEW_CONTEXT = "\n query GET_CATALOG_VIEW_CONTEXT {\n company {\n catalogViewContext {\n catalogViewId\n accessToken\n }\n }\n }\n";
|
package/api/index.d.ts
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/********************************************************************
|
|
2
|
+
* ADOBE CONFIDENTIAL
|
|
3
|
+
* __________________
|
|
4
|
+
*
|
|
5
|
+
* Copyright 2026 Adobe
|
|
6
|
+
* All Rights Reserved.
|
|
7
|
+
*
|
|
8
|
+
* NOTICE: All information contained herein is, and remains
|
|
9
|
+
* the property of Adobe and its suppliers, if any. The intellectual
|
|
10
|
+
* and technical concepts contained herein are proprietary to Adobe
|
|
11
|
+
* and its suppliers and are protected by all applicable intellectual
|
|
12
|
+
* property laws, including trade secret and copyright laws.
|
|
13
|
+
* Dissemination of this information or reproduction of this material
|
|
14
|
+
* is strictly forbidden unless prior written permission is obtained
|
|
15
|
+
* from Adobe.
|
|
16
|
+
*******************************************************************/
|
|
17
|
+
export * from './setCatalogViewHeaders';
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/********************************************************************
|
|
2
|
+
* ADOBE CONFIDENTIAL
|
|
3
|
+
* __________________
|
|
4
|
+
*
|
|
5
|
+
* Copyright 2026 Adobe
|
|
6
|
+
* All Rights Reserved.
|
|
7
|
+
*
|
|
8
|
+
* NOTICE: All information contained herein is, and remains
|
|
9
|
+
* the property of Adobe and its suppliers, if any. The intellectual
|
|
10
|
+
* and technical concepts contained herein are proprietary to Adobe
|
|
11
|
+
* and its suppliers and are protected by all applicable intellectual
|
|
12
|
+
* property laws, including trade secret and copyright laws.
|
|
13
|
+
* Dissemination of this information or reproduction of this material
|
|
14
|
+
* is strictly forbidden unless prior written permission is obtained
|
|
15
|
+
* from Adobe.
|
|
16
|
+
*******************************************************************/
|
|
17
|
+
import type { FetchGraphQL } from '@adobe-commerce/fetch-graphql';
|
|
18
|
+
import type { CatalogViewContext } from '../../types/company';
|
|
19
|
+
/**
|
|
20
|
+
* Manages catalog-view headers for GraphQL requests.
|
|
21
|
+
*
|
|
22
|
+
* Owns two independent headers derived from the company-scoped catalog view
|
|
23
|
+
* context:
|
|
24
|
+
* - `AC-View-Id` (from `catalogViewId`): stamped whenever a view id is present.
|
|
25
|
+
* On clear (logout / null context) it is RESET to the configured default
|
|
26
|
+
* view id when one is provided, or removed when none is configured.
|
|
27
|
+
* - `AC-Catalog-View-Access-Token` (from `accessToken`): stamped only when the
|
|
28
|
+
* token is truthy; removed while the token is null and always removed on clear.
|
|
29
|
+
*
|
|
30
|
+
* The access token is null until a restricted access key is provisioned.
|
|
31
|
+
* Handling the two headers independently is what lets the token start mounting
|
|
32
|
+
* later with zero code change: once the backend returns a non-null token, this
|
|
33
|
+
* manager stamps it automatically.
|
|
34
|
+
*
|
|
35
|
+
* The shared GraphQL client is config-seeded with a default/public `AC-View-Id`
|
|
36
|
+
* (the default view used for guest browsing). So on clear the view-id header is
|
|
37
|
+
* RESET to that configured default rather than bare-removed — mirroring the
|
|
38
|
+
* reset-to-default pattern in `GroupHeaderManager` — preserving the default view
|
|
39
|
+
* scope on the shared client. When no default is configured the header is
|
|
40
|
+
* removed instead, so hosts that seed nothing are not broken. The access-token
|
|
41
|
+
* header has no default and stays remove-on-clear.
|
|
42
|
+
*/
|
|
43
|
+
declare class CatalogViewHeaderManager {
|
|
44
|
+
private catalogViewHeaderSet;
|
|
45
|
+
private headerAppliers;
|
|
46
|
+
private headerRemovers;
|
|
47
|
+
private viewIdHeaderKey;
|
|
48
|
+
private accessTokenHeaderKey;
|
|
49
|
+
private viewIdDefault;
|
|
50
|
+
constructor();
|
|
51
|
+
/**
|
|
52
|
+
* Sets the header key used for the catalog view id
|
|
53
|
+
* @param headerKey - The header name to use for the view id
|
|
54
|
+
*/
|
|
55
|
+
setViewIdHeaderKey(headerKey: string): void;
|
|
56
|
+
/**
|
|
57
|
+
* Sets the header key used for the catalog view access token
|
|
58
|
+
* @param headerKey - The header name to use for the access token
|
|
59
|
+
*/
|
|
60
|
+
setAccessTokenHeaderKey(headerKey: string): void;
|
|
61
|
+
/**
|
|
62
|
+
* Sets the default catalog view id the view-id header is reset to on clear.
|
|
63
|
+
* When empty, the view-id header is removed on clear instead of reset.
|
|
64
|
+
* @param defaultViewId - The default/public view id, or '' to disable reset
|
|
65
|
+
*/
|
|
66
|
+
setViewIdDefault(defaultViewId: string): void;
|
|
67
|
+
/**
|
|
68
|
+
* Configures GraphQL modules that will have catalog-view headers applied
|
|
69
|
+
* @param modules - Array of GraphQL modules with header management functions
|
|
70
|
+
*/
|
|
71
|
+
setFetchGraphQlModules(modules: FetchGraphQL[]): void;
|
|
72
|
+
/**
|
|
73
|
+
* Sets catalog-view headers for all configured GraphQL modules.
|
|
74
|
+
*
|
|
75
|
+
* When the context is null or carries no view id, the clear path runs (see
|
|
76
|
+
* {@link removeCatalogViewHeaders}): the view-id header is reset to the
|
|
77
|
+
* configured default (or removed when none is configured) and the
|
|
78
|
+
* access-token header is removed.
|
|
79
|
+
*
|
|
80
|
+
* The view-id header is always stamped when present; the access-token header
|
|
81
|
+
* is stamped only when the token is truthy and removed otherwise.
|
|
82
|
+
*
|
|
83
|
+
* @param context - The catalog view context, or null to clear the headers
|
|
84
|
+
*/
|
|
85
|
+
setCatalogViewHeaders(context: CatalogViewContext | null): void;
|
|
86
|
+
/**
|
|
87
|
+
* Clears the catalog-view headers on all configured GraphQL modules.
|
|
88
|
+
*
|
|
89
|
+
* The view-id header is RESET to the configured default view id when one is
|
|
90
|
+
* set (preserving the default/public view scope on the shared client), or
|
|
91
|
+
* removed entirely when no default is configured. The access-token header is
|
|
92
|
+
* always removed (it has no default).
|
|
93
|
+
*/
|
|
94
|
+
removeCatalogViewHeaders(): void;
|
|
95
|
+
/**
|
|
96
|
+
* Checks if catalog-view headers are currently set
|
|
97
|
+
* @returns true if the view-id header is set, false otherwise
|
|
98
|
+
*/
|
|
99
|
+
isCatalogViewHeaderSet(): boolean;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Gets the singleton instance of CatalogViewHeaderManager
|
|
103
|
+
* @returns The CatalogViewHeaderManager instance
|
|
104
|
+
*/
|
|
105
|
+
export declare const getCatalogViewHeaderManager: () => CatalogViewHeaderManager;
|
|
106
|
+
export {};
|
package/api.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*! Copyright 2026 Adobe
|
|
2
2
|
All Rights Reserved. */
|
|
3
|
-
var
|
|
3
|
+
var A=Object.defineProperty;var S=(o,e,t)=>e in o?A(o,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[e]=t;var s=(o,e,t)=>S(o,typeof e!="symbol"?e+"":e,t);import{CUSTOMER_FRAGMENT as M,COMPANY_FRAGMENT as _}from"./fragments.js";import{FetchGraphQL as v}from"@dropins/tools/fetch-graphql.js";import{Initializer as O}from"@dropins/tools/lib.js";import{events as p}from"@dropins/tools/event-bus.js";class R{constructor(){s(this,"companyHeaderSet",!1);s(this,"companyHeaderAppliers",[]);s(this,"companyHeaderRemovers",[]);s(this,"headerKey");this.headerKey=i.getConfig().companyHeader,this.setFetchGraphQlModules(i.getConfig().fetchGraphQlModules)}setHeaderKey(e){this.headerKey=e}setFetchGraphQlModules(e){this.companyHeaderAppliers=[],this.companyHeaderRemovers=[],e.forEach(t=>{this.companyHeaderAppliers.push((a,r)=>t.setFetchGraphQlHeader(a,r)),this.companyHeaderRemovers.push(a=>t.removeFetchGraphQlHeader(a))})}setCompanyHeaders(e){if(e===null){this.removeCompanyHeaders();return}this.companyHeaderAppliers.forEach(t=>{t(this.headerKey,e)}),this.companyHeaderSet=!0}removeCompanyHeaders(){this.companyHeaderRemovers.forEach(e=>{e(this.headerKey)}),this.companyHeaderSet=!1}isCompanyHeaderSet(){return this.companyHeaderSet}}let f=null;const u=()=>(f||(f=new R),f);class V{constructor(){s(this,"groupHeaderSet",!1);s(this,"groupHeaderAppliers",[]);s(this,"groupHeaderRemovers",[]);s(this,"headerKey");s(this,"defaultNLICustomerGroupId","b6589fc6ab0dc82cf12099d1c2d40ab994e8410c");this.headerKey=i.getConfig().customerGroupHeader,this.setFetchGraphQlModules(i.getConfig().groupGraphQlModules)}setHeaderKey(e){this.headerKey=e}setFetchGraphQlModules(e){e.forEach(t=>{this.groupHeaderAppliers.push((a,r)=>t.setFetchGraphQlHeader(a,r)),this.groupHeaderRemovers.push(a=>t.setFetchGraphQlHeader(a,this.defaultNLICustomerGroupId))})}setGroupHeaders(e){this.removeGroupHeaders(),e!==null&&(this.groupHeaderAppliers.forEach(t=>{t(this.headerKey,e)}),this.groupHeaderSet=!0)}removeGroupHeaders(){this.groupHeaderRemovers.forEach(e=>{e(this.headerKey)}),this.groupHeaderSet=!1}isGroupHeaderSet(){return this.groupHeaderSet}}let H=null;const C=()=>(H||(H=new V),H);class K{constructor(){s(this,"catalogViewHeaderSet",!1);s(this,"headerAppliers",[]);s(this,"headerRemovers",[]);s(this,"viewIdHeaderKey");s(this,"accessTokenHeaderKey");s(this,"viewIdDefault");this.viewIdHeaderKey=i.getConfig().catalogViewHeader,this.accessTokenHeaderKey=i.getConfig().catalogViewAccessTokenHeader,this.viewIdDefault=i.getConfig().catalogViewDefault,this.setFetchGraphQlModules(i.getConfig().catalogViewGraphQlModules)}setViewIdHeaderKey(e){this.viewIdHeaderKey=e}setAccessTokenHeaderKey(e){this.accessTokenHeaderKey=e}setViewIdDefault(e){this.viewIdDefault=e}setFetchGraphQlModules(e){this.headerAppliers=[],this.headerRemovers=[],e.forEach(t=>{this.headerAppliers.push((a,r)=>t.setFetchGraphQlHeader(a,r)),this.headerRemovers.push(a=>t.removeFetchGraphQlHeader(a))})}setCatalogViewHeaders(e){if(!e||!e.catalogViewId){this.removeCatalogViewHeaders();return}if(this.headerAppliers.forEach(t=>{t(this.viewIdHeaderKey,e.catalogViewId)}),e.accessToken){const t=e.accessToken;this.headerAppliers.forEach(a=>{a(this.accessTokenHeaderKey,t)})}else this.headerRemovers.forEach(t=>{t(this.accessTokenHeaderKey)});this.catalogViewHeaderSet=!0}removeCatalogViewHeaders(){this.viewIdDefault?this.headerAppliers.forEach(e=>{e(this.viewIdHeaderKey,this.viewIdDefault)}):this.headerRemovers.forEach(e=>{e(this.viewIdHeaderKey)}),this.headerRemovers.forEach(e=>{e(this.accessTokenHeaderKey)}),this.catalogViewHeaderSet=!1}isCatalogViewHeaderSet(){return this.catalogViewHeaderSet}}let G=null;const E=()=>(G||(G=new K),G),N=`
|
|
4
4
|
query GET_CUSTOMER_COMPANIES($pageSize: Int) {
|
|
5
5
|
customer {
|
|
6
6
|
...CUSTOMER_FRAGMENT
|
|
@@ -13,13 +13,22 @@ var S=Object.defineProperty;var M=(s,e,r)=>e in s?S(s,e,{enumerable:!0,configura
|
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
${
|
|
17
|
-
${
|
|
18
|
-
`,
|
|
16
|
+
${M}
|
|
17
|
+
${_}
|
|
18
|
+
`,Q=`
|
|
19
19
|
query GET_CUSTOMER_GROUP {
|
|
20
20
|
customerGroup {
|
|
21
21
|
uid
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
|
-
`,
|
|
24
|
+
`,F=`
|
|
25
|
+
query GET_CATALOG_VIEW_CONTEXT {
|
|
26
|
+
company {
|
|
27
|
+
catalogViewContext {
|
|
28
|
+
catalogViewId
|
|
29
|
+
accessToken
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
`,P=["graphql-input","graphql-no-such-entity","graphql-authorization","graphql-authentication","graphql-already-exists","graphql-server"],U=/cannot query field .*catalogViewContext/i,n=class n{constructor(){s(this,"EMPTY_CUSTOMER_COMPANY_CONTEXT",{currentCompany:{id:"",name:""},customerCompanies:[],customerGroupId:""});s(this,"cache",null);s(this,"transformCompanyToOption",e=>({text:e.name,value:e.id}))}static getInstance(){return n.instance??(n.instance=new n)}async processCustomerGroupId(e){const t=Uint8Array.from(atob(e),r=>r.charCodeAt(0)),a=await crypto.subtle.digest("SHA-1",t);return Array.from(new Uint8Array(a)).map(r=>r.toString(16).padStart(2,"0")).join("")}isUserAuthenticated(){var e;return!!((e=Y().fetchGraphQlHeaders)!=null&&e.Authorization)}resetCache(){this.cache=null}async updateCustomerGroup(){if(!this.isUserAuthenticated())return null;try{const e=await T(Q);if(e.errors)return null;const t=await this.processCustomerGroupId(e.data.customerGroup.uid);return this.cache&&(this.cache.customerGroupId=t),t}catch(e){return console.error(e),null}}async getCatalogViewContext(){var e,t,a;if(!this.isUserAuthenticated())return null;try{const r=await T(F);return(e=r.errors)!=null&&e.length?(this.isCatalogViewFieldAbsent(r.errors)?console.debug("Catalog view context field not available on backend; skipping view headers.",r.errors):console.error("Catalog view context request returned errors; skipping view headers.",r.errors),null):((a=(t=r.data)==null?void 0:t.company)==null?void 0:a.catalogViewContext)??null}catch(r){return console.error(r),null}}isCatalogViewFieldAbsent(e){return e.some(a=>{var r;return P.includes(((r=a==null?void 0:a.extensions)==null?void 0:r.category)??"")})?!1:e.some(a=>{var r;return U.test((a==null?void 0:a.message)??"")||((r=a==null?void 0:a.extensions)==null?void 0:r.code)==="GRAPHQL_VALIDATION_FAILED"})}async getCustomerCompanyInfo(e=100){if(this.cache)return this.cache;if(!this.isUserAuthenticated())return this.EMPTY_CUSTOMER_COMPANY_CONTEXT;try{const t=await T(N,{variables:{pageSize:e}});if(t.errors)return this.EMPTY_CUSTOMER_COMPANY_CONTEXT;const a=t.data,r=await this.processCustomerGroupId(t.data.customerGroup.uid),m=a.customer.companies.items.filter(d=>d.status==="APPROVED"||d.status==="BLOCKED").map(this.transformCompanyToOption);return this.cache={currentCompany:a.company,customerCompanies:m,customerGroupId:r},this.cache}catch(t){return console.error(t),this.EMPTY_CUSTOMER_COMPANY_CONTEXT}}};s(n,"instance");let g=n;const k=(o=100)=>g.getInstance().getCustomerCompanyInfo(o),W=()=>g.getInstance().updateCustomerGroup(),D=()=>g.getInstance().getCatalogViewContext(),w=async o=>{if(!o){E().removeCatalogViewHeaders();return}const e=await D();E().setCatalogViewHeaders(e)},l=new O({init:async o=>{const e={fetchGraphQlModules:[],groupGraphQlModules:[],catalogViewGraphQlModules:[],companyHeader:"X-Adobe-Company",customerGroupHeader:"Magento-Customer-Group",catalogViewHeader:"AC-View-Id",catalogViewAccessTokenHeader:"AC-Catalog-View-Access-Token",catalogViewDefault:"",companySessionStorageKey:"DROPIN__COMPANYSWITCHER__COMPANY__CONTEXT",groupSessionStorageKey:"DROPIN__COMPANYSWITCHER__GROUP__CONTEXT"};l.config.setConfig({...e,...o});const t=sessionStorage.getItem(l.config.getConfig().groupSessionStorageKey),a=sessionStorage.getItem(l.config.getConfig().companySessionStorageKey);a&&!u().isCompanyHeaderSet()&&(u().setCompanyHeaders(a),p.emit("companyContext/changed",a)),t&&!C().isGroupHeaderSet()&&C().setGroupHeaders(t),p.on("companyContext/changed",async r=>{await w(r)}),p.on("authenticated",async r=>{var m;const c=l.config.getConfig();if(!r)sessionStorage.removeItem(c.companySessionStorageKey),sessionStorage.removeItem(c.groupSessionStorageKey),u().removeCompanyHeaders(),C().removeGroupHeaders(),E().removeCatalogViewHeaders(),p.emit("companyContext/changed",null);else{const d=sessionStorage.getItem(c.companySessionStorageKey);if(d||u().isCompanyHeaderSet()){d&&await w(d);return}const h=await k();if(h.customerCompanies.length<2){(m=h.currentCompany)!=null&&m.id&&await w(h.currentCompany.id);return}const y=h.currentCompany.id,I=h.customerGroupId;u().setCompanyHeaders(y),C().setGroupHeaders(I),sessionStorage.setItem(c.companySessionStorageKey,y),sessionStorage.setItem(c.groupSessionStorageKey,I),p.emit("companyContext/changed",y)}},{eager:!0})},listeners:()=>[]}),i=l.config,{setEndpoint:z,setFetchGraphQlHeader:B,removeFetchGraphQlHeader:$,setFetchGraphQlHeaders:j,fetchGraphQl:T,getConfig:Y}=new v().getMethods();export{g as CustomerCompanyContext,i as config,T as fetchGraphQl,D as getCatalogViewContext,E as getCatalogViewHeaderManager,u as getCompanyHeaderManager,Y as getConfig,k as getCustomerCompanyInfo,C as getGroupHeaderManager,l as initialize,$ as removeFetchGraphQlHeader,z as setEndpoint,B as setFetchGraphQlHeader,j as setFetchGraphQlHeaders,W as updateCustomerGroup};
|
|
25
34
|
//# sourceMappingURL=api.js.map
|
package/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sources":["/@dropins/storefront-company-switcher/src/api/setCompanyHeaders/setCompanyHeaders.ts","/@dropins/storefront-company-switcher/src/api/setGroupHeaders/setGroupHeaders.ts","/@dropins/storefront-company-switcher/src/api/customerCompanyContext/graphql/customerCompanyContext.graphql.ts","/@dropins/storefront-company-switcher/src/api/customerCompanyContext/graphql/customerGroupContext.graphql.ts","/@dropins/storefront-company-switcher/src/api/customerCompanyContext/customerCompanyContext.ts","/@dropins/storefront-company-switcher/src/api/initialize/initialize.ts","/@dropins/storefront-company-switcher/src/api/fetch-graphql/fetch-graphql.ts"],"sourcesContent":["/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\nimport type { FetchGraphQL, setFetchGraphQlHeader, removeFetchGraphQlHeader } from '@adobe-commerce/fetch-graphql';\nimport { config } from '@/company-switcher/api';\n\n/**\n * Manages company-specific headers for GraphQL requests.\n * Singleton class that handles setting and removing company headers across multiple GraphQL modules.\n */\nclass CompanyHeaderManager {\n private companyHeaderSet: boolean = false;\n private companyHeaderAppliers: typeof setFetchGraphQlHeader[] = [];\n private companyHeaderRemovers: typeof removeFetchGraphQlHeader[] = [];\n private headerKey: string;\n\n constructor() {\n this.headerKey = config.getConfig().companyHeader;\n this.setFetchGraphQlModules(config.getConfig().fetchGraphQlModules);\n }\n\n /**\n * Sets the header key used for company identification\n * @param headerKey - The header name to use for company ID\n */\n public setHeaderKey(headerKey: string): void {\n this.headerKey = headerKey;\n }\n\n /**\n * Configures GraphQL modules that will have company headers applied\n * @param modules - Array of GraphQL modules with header management functions\n */\n public setFetchGraphQlModules(modules: FetchGraphQL[]): void {\n this.companyHeaderAppliers = [];\n this.companyHeaderRemovers = [];\n modules.forEach((module: FetchGraphQL) => {\n this.companyHeaderAppliers.push((key: string, value: string) => \n module.setFetchGraphQlHeader(key, value)\n );\n this.companyHeaderRemovers.push((key: string) => \n module.removeFetchGraphQlHeader(key)\n );\n });\n }\n\n /**\n * Sets company headers for all configured GraphQL modules\n * @param companyId - The company ID to set in headers, or null to remove headers\n */\n public setCompanyHeaders(companyId: string | null): void {\n if (companyId === null) {\n this.removeCompanyHeaders();\n return;\n }\n this.companyHeaderAppliers.forEach((setFn) => {\n setFn(this.headerKey, companyId);\n });\n this.companyHeaderSet = true;\n }\n\n /**\n * Removes company headers from all configured GraphQL modules\n */\n public removeCompanyHeaders(): void {\n this.companyHeaderRemovers.forEach((removeFn) => {\n removeFn(this.headerKey);\n });\n this.companyHeaderSet = false;\n }\n\n /**\n * Checks if company headers are currently set\n * @returns true if company headers are set, false otherwise\n */\n public isCompanyHeaderSet(): boolean {\n return this.companyHeaderSet;\n }\n}\n\nlet _companyHeaderManager: CompanyHeaderManager | null = null;\n\n/**\n * Gets the singleton instance of CompanyHeaderManager\n * @returns The CompanyHeaderManager instance\n */\nexport const getCompanyHeaderManager = () => {\n if (!_companyHeaderManager) {\n _companyHeaderManager = new CompanyHeaderManager();\n }\n return _companyHeaderManager;\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\nimport type { FetchGraphQL, setFetchGraphQlHeader } from '@adobe-commerce/fetch-graphql';\nimport { config } from '@/company-switcher/api';\n\n/**\n * Manages customer group headers for GraphQL requests.\n * Singleton class that handles setting and removing group headers across multiple GraphQL modules.\n */\nclass GroupHeaderManager {\n private groupHeaderSet: boolean = false;\n private groupHeaderAppliers: typeof setFetchGraphQlHeader[] = [];\n private groupHeaderRemovers: ((key: string) => void)[] = [];\n private headerKey: string;\n private defaultNLICustomerGroupId = 'b6589fc6ab0dc82cf12099d1c2d40ab994e8410c';\n\n\n constructor() {\n this.headerKey = config.getConfig().customerGroupHeader;\n this.setFetchGraphQlModules(config.getConfig().groupGraphQlModules);\n }\n\n /**\n * Sets the header key used for customer group identification\n * @param headerKey - The header name to use for group ID\n */\n public setHeaderKey(headerKey: string): void {\n this.headerKey = headerKey;\n }\n\n /**\n * Configures GraphQL modules that will have group headers applied\n * @param modules - Array of GraphQL modules with header management functions\n */\n public setFetchGraphQlModules(modules: FetchGraphQL[]): void {\n modules.forEach((module: FetchGraphQL) => {\n this.groupHeaderAppliers.push((key: string, value: string) => \n module.setFetchGraphQlHeader(key, value)\n );\n this.groupHeaderRemovers.push((key: string) => \n module.setFetchGraphQlHeader(key, this.defaultNLICustomerGroupId)\n );\n });\n }\n\n /**\n * Sets customer group headers for all configured GraphQL modules.\n * Always removes existing headers first before setting new ones.\n * @param groupId - The group ID to set in headers, or null to only remove headers\n */\n public setGroupHeaders(groupId: string | null): void {\n this.removeGroupHeaders();\n if (groupId === null) {\n return;\n }\n this.groupHeaderAppliers.forEach((setFn) => {\n setFn(this.headerKey, groupId);\n });\n this.groupHeaderSet = true;\n }\n\n /**\n * Removes customer group headers from all configured GraphQL modules\n */\n public removeGroupHeaders(): void {\n this.groupHeaderRemovers.forEach((removeFn) => {\n removeFn(this.headerKey);\n });\n this.groupHeaderSet = false;\n }\n\n /**\n * Checks if customer group headers are currently set\n * @returns true if group headers are set, false otherwise\n */\n public isGroupHeaderSet(): boolean {\n return this.groupHeaderSet;\n }\n}\n\nlet _groupHeaderManager: GroupHeaderManager | null = null;\n\n/**\n * Gets the singleton instance of GroupHeaderManager\n * @returns The GroupHeaderManager instance\n */\nexport const getGroupHeaderManager = () => {\n if (!_groupHeaderManager) {\n _groupHeaderManager = new GroupHeaderManager();\n }\n return _groupHeaderManager;\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { COMPANY_FRAGMENT, CUSTOMER_FRAGMENT } from '@/company-switcher/api/fragments';\n\nexport const GET_CUSTOMER_COMPANY_CONTEXT = /* GraphQL */ `\n query GET_CUSTOMER_COMPANIES($pageSize: Int) {\n customer {\n ...CUSTOMER_FRAGMENT\n }\n company {\n ...COMPANY_FRAGMENT\n }\n customerGroup {\n uid\n }\n }\n\n ${CUSTOMER_FRAGMENT}\n ${COMPANY_FRAGMENT}\n`;\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nexport const GET_CUSTOMER_GROUP_CONTEXT = `\n query GET_CUSTOMER_GROUP {\n customerGroup {\n uid\n }\n }\n`;\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { fetchGraphQl, getConfig } from \"@/company-switcher/api\";\nimport type { Company, CompanyOption, CustomerCompanyInfo, GraphQLResponse } from '@/company-switcher/types/company';\nimport { GET_CUSTOMER_COMPANY_CONTEXT } from './graphql/customerCompanyContext.graphql';\nimport { GET_CUSTOMER_GROUP_CONTEXT } from './graphql/customerGroupContext.graphql';\n\nexport class CustomerCompanyContext {\n private static instance: CustomerCompanyContext;\n\n // Constants\n private readonly EMPTY_CUSTOMER_COMPANY_CONTEXT: CustomerCompanyInfo = {\n currentCompany: { id: '', name: '' },\n customerCompanies: [],\n customerGroupId: '',\n };\n\n private cache: CustomerCompanyInfo | null = null;\n\n /**\n * Get singleton instance\n */\n static getInstance(): CustomerCompanyContext {\n return CustomerCompanyContext.instance ??= new CustomerCompanyContext();\n }\n\n /**\n * Transforms a company object into a company option for UI components\n */\n private transformCompanyToOption = (company: Company): CompanyOption => ({\n text: company.name,\n value: company.id\n });\n\n /**\n * Decodes base64 string and returns SHA1 hash\n */\n private async processCustomerGroupId(base64String: string): Promise<string> {\n const decoded = Uint8Array.from(atob(base64String), c => c.charCodeAt(0));\n const hashBuffer = await crypto.subtle.digest('SHA-1', decoded);\n return Array.from(new Uint8Array(hashBuffer)).map(b => b.toString(16).padStart(2, '0')).join('');\n }\n\n /**\n * Checks if the user is authenticated by verifying the Authorization header\n */\n private isUserAuthenticated(): boolean {\n return Boolean(getConfig().fetchGraphQlHeaders?.Authorization);\n }\n\n resetCache(): void {\n this.cache = null;\n }\n\n /**\n * Fetches and updates only the customer group information in the cache\n * \n * @returns Promise containing the updated customer group ID\n * @throws Will not throw errors - returns null on failure\n */\n async updateCustomerGroup(): Promise<string | null> {\n if (!this.isUserAuthenticated()) {\n return null;\n }\n\n try {\n const response = await fetchGraphQl<{ customerGroup: { uid: string } }>(GET_CUSTOMER_GROUP_CONTEXT);\n if (response.errors) {\n return null;\n }\n const customerGroupId = await this.processCustomerGroupId(response.data.customerGroup.uid);\n if (this.cache) {\n this.cache.customerGroupId = customerGroupId;\n }\n return customerGroupId;\n } catch (e) {\n console.error(e)\n return null;\n }\n }\n\n /**\n * Fetches customer company information including the current company and all available companies\n * \n * @returns Promise containing current company and list of available companies\n * @throws Will not throw errors - returns empty data on failure\n */\n async getCustomerCompanyInfo(pageSize = 100): Promise<CustomerCompanyInfo> {\n // Return cached data if available\n if (this.cache) {\n return this.cache;\n }\n\n // Return empty data if user is not authenticated\n if (!this.isUserAuthenticated()) {\n return this.EMPTY_CUSTOMER_COMPANY_CONTEXT;\n }\n\n try {\n // Fetch company data from GraphQL API\n const response = (await fetchGraphQl<GraphQLResponse>(GET_CUSTOMER_COMPANY_CONTEXT, { variables: { pageSize } }));\n if (response.errors) {\n return this.EMPTY_CUSTOMER_COMPANY_CONTEXT;\n }\n\n const data = response.data;\n const customerGroup = await this.processCustomerGroupId(response.data.customerGroup.uid);\n // Whitelist approach: only allow APPROVED and BLOCKED companies\n // BLOCKED companies allow users to log in and view but not perform actions\n const activeCompanies = data.customer.companies.items.filter(\n company => company.status === 'APPROVED' || company.status === 'BLOCKED'\n );\n const customerCompanies = activeCompanies.map(this.transformCompanyToOption);\n\n this.cache = {\n currentCompany: data.company,\n customerCompanies,\n customerGroupId: customerGroup\n }\n return this.cache;\n } catch (e) {\n console.error(e);\n return this.EMPTY_CUSTOMER_COMPANY_CONTEXT;\n }\n }\n}\n\nexport const getCustomerCompanyInfo = (pageSize = 100): Promise<CustomerCompanyInfo> => {\n return CustomerCompanyContext.getInstance().getCustomerCompanyInfo(pageSize);\n};\n\nexport const updateCustomerGroup = (): Promise<string | null> => {\n return CustomerCompanyContext.getInstance().updateCustomerGroup();\n};","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport type { FetchGraphQL } from '@adobe-commerce/fetch-graphql';\nimport { Initializer } from '@adobe-commerce/elsie/lib';\nimport { Lang } from '@adobe-commerce/elsie/i18n';\nimport { getCompanyHeaderManager } from '@/company-switcher/api/setCompanyHeaders/setCompanyHeaders';\nimport { getGroupHeaderManager } from '@/company-switcher/api/setGroupHeaders/setGroupHeaders';\nimport { getCustomerCompanyInfo } from '@/company-switcher/api/customerCompanyContext/customerCompanyContext';\nimport { events } from '@adobe-commerce/event-bus';\n\n/**\n * Configuration properties for the company switcher initialization\n */\ninterface ConfigProps {\n /** Optional language definitions for internationalization */\n langDefinitions?: Lang;\n /** HTTP header name for company identification */\n companyHeader: string;\n /** HTTP header name for customer group identification */\n customerGroupHeader: string;\n /** Session storage key for persisting company context */\n companySessionStorageKey: string;\n /** Session storage key for persisting group context */\n groupSessionStorageKey: string;\n /** GraphQL modules that will have company headers applied */\n fetchGraphQlModules: FetchGraphQL[];\n /** GraphQL modules that will have group headers applied */\n groupGraphQlModules: FetchGraphQL[];\n}\n\n/**\n * Initializer for the company switcher drop-in.\n * Configures headers, storage, and GraphQL modules for company management.\n */\nexport const initialize = new Initializer<ConfigProps>({\n init: async (config) => {\n const defaultConfig = {\n fetchGraphQlModules: [],\n groupGraphQlModules: [],\n companyHeader: 'X-Adobe-Company',\n customerGroupHeader: 'Magento-Customer-Group',\n companySessionStorageKey: 'DROPIN__COMPANYSWITCHER__COMPANY__CONTEXT',\n groupSessionStorageKey: 'DROPIN__COMPANYSWITCHER__GROUP__CONTEXT'\n };\n initialize.config.setConfig({ ...defaultConfig, ...config });\n\n const groupId = sessionStorage.getItem(initialize.config.getConfig().groupSessionStorageKey);\n const companyId = sessionStorage.getItem(initialize.config.getConfig().companySessionStorageKey);\n if (companyId && !getCompanyHeaderManager().isCompanyHeaderSet()) {\n getCompanyHeaderManager().setCompanyHeaders(companyId);\n events.emit('companyContext/changed', companyId);\n }\n if (groupId && !getGroupHeaderManager().isGroupHeaderSet()) {\n getGroupHeaderManager().setGroupHeaders(groupId);\n }\n\n events.on('authenticated', async (authenticated: boolean) => {\n const config = initialize.config.getConfig();\n if (!authenticated) {\n sessionStorage.removeItem(config.companySessionStorageKey);\n sessionStorage.removeItem(config.groupSessionStorageKey);\n getCompanyHeaderManager().removeCompanyHeaders();\n getGroupHeaderManager().removeGroupHeaders();\n events.emit('companyContext/changed', null);\n } else {\n const storedCompanyId = sessionStorage.getItem(config.companySessionStorageKey);\n if (storedCompanyId || getCompanyHeaderManager().isCompanyHeaderSet()) {\n return;\n }\n const companyInfo = await getCustomerCompanyInfo();\n if (companyInfo.customerCompanies.length < 2) {\n return;\n }\n\n const currentCompanyId = companyInfo.currentCompany.id;\n const groupId = companyInfo.customerGroupId;\n getCompanyHeaderManager().setCompanyHeaders(currentCompanyId);\n getGroupHeaderManager().setGroupHeaders(groupId);\n sessionStorage.setItem(config.companySessionStorageKey, currentCompanyId);\n sessionStorage.setItem(config.groupSessionStorageKey, groupId);\n events.emit('companyContext/changed', currentCompanyId);\n }\n }, { eager: true });\n },\n listeners: () => []\n});\n\n/**\n * Configuration object for getting and setting company switcher configuration.\n * Provides methods to access and update the current configuration.\n */\nexport const config = initialize.config;\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { FetchGraphQL } from '@adobe-commerce/fetch-graphql';\n\n/**\n * GraphQL client methods for making API requests.\n * Provides methods to configure endpoints, headers, and execute GraphQL queries.\n */\nexport const {\n /** Sets the GraphQL endpoint URL */\n setEndpoint,\n /** Sets a single GraphQL header */\n setFetchGraphQlHeader,\n /** Removes a GraphQL header */\n removeFetchGraphQlHeader,\n /** Sets multiple GraphQL headers at once */\n setFetchGraphQlHeaders,\n /** Executes a GraphQL query or mutation */\n fetchGraphQl,\n /** Gets the current configuration */\n getConfig,\n} = new FetchGraphQL().getMethods();\n"],"names":["CompanyHeaderManager","__publicField","config","headerKey","modules","module","key","value","companyId","setFn","removeFn","_companyHeaderManager","getCompanyHeaderManager","GroupHeaderManager","groupId","_groupHeaderManager","getGroupHeaderManager","GET_CUSTOMER_COMPANY_CONTEXT","CUSTOMER_FRAGMENT","COMPANY_FRAGMENT","GET_CUSTOMER_GROUP_CONTEXT","_CustomerCompanyContext","company","base64String","decoded","c","hashBuffer","b","_a","getConfig","response","fetchGraphQl","customerGroupId","pageSize","data","customerGroup","customerCompanies","e","CustomerCompanyContext","getCustomerCompanyInfo","updateCustomerGroup","initialize","Initializer","defaultConfig","events","authenticated","companyInfo","currentCompanyId","setEndpoint","setFetchGraphQlHeader","removeFetchGraphQlHeader","setFetchGraphQlHeaders","FetchGraphQL"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"api.js","sources":["/@dropins/storefront-company-switcher/src/api/setCompanyHeaders/setCompanyHeaders.ts","/@dropins/storefront-company-switcher/src/api/setGroupHeaders/setGroupHeaders.ts","/@dropins/storefront-company-switcher/src/api/setCatalogViewHeaders/setCatalogViewHeaders.ts","/@dropins/storefront-company-switcher/src/api/customerCompanyContext/graphql/customerCompanyContext.graphql.ts","/@dropins/storefront-company-switcher/src/api/customerCompanyContext/graphql/customerGroupContext.graphql.ts","/@dropins/storefront-company-switcher/src/api/customerCompanyContext/graphql/catalogViewContext.graphql.ts","/@dropins/storefront-company-switcher/src/api/customerCompanyContext/customerCompanyContext.ts","/@dropins/storefront-company-switcher/src/api/initialize/initialize.ts","/@dropins/storefront-company-switcher/src/api/fetch-graphql/fetch-graphql.ts"],"sourcesContent":["/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\nimport type { FetchGraphQL, setFetchGraphQlHeader, removeFetchGraphQlHeader } from '@adobe-commerce/fetch-graphql';\nimport { config } from '@/company-switcher/api';\n\n/**\n * Manages company-specific headers for GraphQL requests.\n * Singleton class that handles setting and removing company headers across multiple GraphQL modules.\n */\nclass CompanyHeaderManager {\n private companyHeaderSet: boolean = false;\n private companyHeaderAppliers: typeof setFetchGraphQlHeader[] = [];\n private companyHeaderRemovers: typeof removeFetchGraphQlHeader[] = [];\n private headerKey: string;\n\n constructor() {\n this.headerKey = config.getConfig().companyHeader;\n this.setFetchGraphQlModules(config.getConfig().fetchGraphQlModules);\n }\n\n /**\n * Sets the header key used for company identification\n * @param headerKey - The header name to use for company ID\n */\n public setHeaderKey(headerKey: string): void {\n this.headerKey = headerKey;\n }\n\n /**\n * Configures GraphQL modules that will have company headers applied\n * @param modules - Array of GraphQL modules with header management functions\n */\n public setFetchGraphQlModules(modules: FetchGraphQL[]): void {\n this.companyHeaderAppliers = [];\n this.companyHeaderRemovers = [];\n modules.forEach((module: FetchGraphQL) => {\n this.companyHeaderAppliers.push((key: string, value: string) => \n module.setFetchGraphQlHeader(key, value)\n );\n this.companyHeaderRemovers.push((key: string) => \n module.removeFetchGraphQlHeader(key)\n );\n });\n }\n\n /**\n * Sets company headers for all configured GraphQL modules\n * @param companyId - The company ID to set in headers, or null to remove headers\n */\n public setCompanyHeaders(companyId: string | null): void {\n if (companyId === null) {\n this.removeCompanyHeaders();\n return;\n }\n this.companyHeaderAppliers.forEach((setFn) => {\n setFn(this.headerKey, companyId);\n });\n this.companyHeaderSet = true;\n }\n\n /**\n * Removes company headers from all configured GraphQL modules\n */\n public removeCompanyHeaders(): void {\n this.companyHeaderRemovers.forEach((removeFn) => {\n removeFn(this.headerKey);\n });\n this.companyHeaderSet = false;\n }\n\n /**\n * Checks if company headers are currently set\n * @returns true if company headers are set, false otherwise\n */\n public isCompanyHeaderSet(): boolean {\n return this.companyHeaderSet;\n }\n}\n\nlet _companyHeaderManager: CompanyHeaderManager | null = null;\n\n/**\n * Gets the singleton instance of CompanyHeaderManager\n * @returns The CompanyHeaderManager instance\n */\nexport const getCompanyHeaderManager = () => {\n if (!_companyHeaderManager) {\n _companyHeaderManager = new CompanyHeaderManager();\n }\n return _companyHeaderManager;\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\nimport type { FetchGraphQL, setFetchGraphQlHeader } from '@adobe-commerce/fetch-graphql';\nimport { config } from '@/company-switcher/api';\n\n/**\n * Manages customer group headers for GraphQL requests.\n * Singleton class that handles setting and removing group headers across multiple GraphQL modules.\n */\nclass GroupHeaderManager {\n private groupHeaderSet: boolean = false;\n private groupHeaderAppliers: typeof setFetchGraphQlHeader[] = [];\n private groupHeaderRemovers: ((key: string) => void)[] = [];\n private headerKey: string;\n private defaultNLICustomerGroupId = 'b6589fc6ab0dc82cf12099d1c2d40ab994e8410c';\n\n\n constructor() {\n this.headerKey = config.getConfig().customerGroupHeader;\n this.setFetchGraphQlModules(config.getConfig().groupGraphQlModules);\n }\n\n /**\n * Sets the header key used for customer group identification\n * @param headerKey - The header name to use for group ID\n */\n public setHeaderKey(headerKey: string): void {\n this.headerKey = headerKey;\n }\n\n /**\n * Configures GraphQL modules that will have group headers applied\n * @param modules - Array of GraphQL modules with header management functions\n */\n public setFetchGraphQlModules(modules: FetchGraphQL[]): void {\n modules.forEach((module: FetchGraphQL) => {\n this.groupHeaderAppliers.push((key: string, value: string) => \n module.setFetchGraphQlHeader(key, value)\n );\n this.groupHeaderRemovers.push((key: string) => \n module.setFetchGraphQlHeader(key, this.defaultNLICustomerGroupId)\n );\n });\n }\n\n /**\n * Sets customer group headers for all configured GraphQL modules.\n * Always removes existing headers first before setting new ones.\n * @param groupId - The group ID to set in headers, or null to only remove headers\n */\n public setGroupHeaders(groupId: string | null): void {\n this.removeGroupHeaders();\n if (groupId === null) {\n return;\n }\n this.groupHeaderAppliers.forEach((setFn) => {\n setFn(this.headerKey, groupId);\n });\n this.groupHeaderSet = true;\n }\n\n /**\n * Removes customer group headers from all configured GraphQL modules\n */\n public removeGroupHeaders(): void {\n this.groupHeaderRemovers.forEach((removeFn) => {\n removeFn(this.headerKey);\n });\n this.groupHeaderSet = false;\n }\n\n /**\n * Checks if customer group headers are currently set\n * @returns true if group headers are set, false otherwise\n */\n public isGroupHeaderSet(): boolean {\n return this.groupHeaderSet;\n }\n}\n\nlet _groupHeaderManager: GroupHeaderManager | null = null;\n\n/**\n * Gets the singleton instance of GroupHeaderManager\n * @returns The GroupHeaderManager instance\n */\nexport const getGroupHeaderManager = () => {\n if (!_groupHeaderManager) {\n _groupHeaderManager = new GroupHeaderManager();\n }\n return _groupHeaderManager;\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2026 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\nimport type { FetchGraphQL, setFetchGraphQlHeader, removeFetchGraphQlHeader } from '@adobe-commerce/fetch-graphql';\nimport { config } from '@/company-switcher/api';\nimport type { CatalogViewContext } from '@/company-switcher/types/company';\n\n/**\n * Manages catalog-view headers for GraphQL requests.\n *\n * Owns two independent headers derived from the company-scoped catalog view\n * context:\n * - `AC-View-Id` (from `catalogViewId`): stamped whenever a view id is present.\n * On clear (logout / null context) it is RESET to the configured default\n * view id when one is provided, or removed when none is configured.\n * - `AC-Catalog-View-Access-Token` (from `accessToken`): stamped only when the\n * token is truthy; removed while the token is null and always removed on clear.\n *\n * The access token is null until a restricted access key is provisioned.\n * Handling the two headers independently is what lets the token start mounting\n * later with zero code change: once the backend returns a non-null token, this\n * manager stamps it automatically.\n *\n * The shared GraphQL client is config-seeded with a default/public `AC-View-Id`\n * (the default view used for guest browsing). So on clear the view-id header is\n * RESET to that configured default rather than bare-removed — mirroring the\n * reset-to-default pattern in `GroupHeaderManager` — preserving the default view\n * scope on the shared client. When no default is configured the header is\n * removed instead, so hosts that seed nothing are not broken. The access-token\n * header has no default and stays remove-on-clear.\n */\nclass CatalogViewHeaderManager {\n private catalogViewHeaderSet: boolean = false;\n private headerAppliers: typeof setFetchGraphQlHeader[] = [];\n private headerRemovers: typeof removeFetchGraphQlHeader[] = [];\n private viewIdHeaderKey: string;\n private accessTokenHeaderKey: string;\n private viewIdDefault: string;\n\n constructor() {\n this.viewIdHeaderKey = config.getConfig().catalogViewHeader;\n this.accessTokenHeaderKey = config.getConfig().catalogViewAccessTokenHeader;\n this.viewIdDefault = config.getConfig().catalogViewDefault;\n this.setFetchGraphQlModules(config.getConfig().catalogViewGraphQlModules);\n }\n\n /**\n * Sets the header key used for the catalog view id\n * @param headerKey - The header name to use for the view id\n */\n public setViewIdHeaderKey(headerKey: string): void {\n this.viewIdHeaderKey = headerKey;\n }\n\n /**\n * Sets the header key used for the catalog view access token\n * @param headerKey - The header name to use for the access token\n */\n public setAccessTokenHeaderKey(headerKey: string): void {\n this.accessTokenHeaderKey = headerKey;\n }\n\n /**\n * Sets the default catalog view id the view-id header is reset to on clear.\n * When empty, the view-id header is removed on clear instead of reset.\n * @param defaultViewId - The default/public view id, or '' to disable reset\n */\n public setViewIdDefault(defaultViewId: string): void {\n this.viewIdDefault = defaultViewId;\n }\n\n /**\n * Configures GraphQL modules that will have catalog-view headers applied\n * @param modules - Array of GraphQL modules with header management functions\n */\n public setFetchGraphQlModules(modules: FetchGraphQL[]): void {\n this.headerAppliers = [];\n this.headerRemovers = [];\n modules.forEach((module: FetchGraphQL) => {\n this.headerAppliers.push((key: string, value: string) =>\n module.setFetchGraphQlHeader(key, value)\n );\n this.headerRemovers.push((key: string) =>\n module.removeFetchGraphQlHeader(key)\n );\n });\n }\n\n /**\n * Sets catalog-view headers for all configured GraphQL modules.\n *\n * When the context is null or carries no view id, the clear path runs (see\n * {@link removeCatalogViewHeaders}): the view-id header is reset to the\n * configured default (or removed when none is configured) and the\n * access-token header is removed.\n *\n * The view-id header is always stamped when present; the access-token header\n * is stamped only when the token is truthy and removed otherwise.\n *\n * @param context - The catalog view context, or null to clear the headers\n */\n public setCatalogViewHeaders(context: CatalogViewContext | null): void {\n if (!context || !context.catalogViewId) {\n this.removeCatalogViewHeaders();\n return;\n }\n\n this.headerAppliers.forEach((setFn) => {\n setFn(this.viewIdHeaderKey, context.catalogViewId);\n });\n\n if (context.accessToken) {\n const token = context.accessToken;\n this.headerAppliers.forEach((setFn) => {\n setFn(this.accessTokenHeaderKey, token);\n });\n } else {\n this.headerRemovers.forEach((removeFn) => {\n removeFn(this.accessTokenHeaderKey);\n });\n }\n\n this.catalogViewHeaderSet = true;\n }\n\n /**\n * Clears the catalog-view headers on all configured GraphQL modules.\n *\n * The view-id header is RESET to the configured default view id when one is\n * set (preserving the default/public view scope on the shared client), or\n * removed entirely when no default is configured. The access-token header is\n * always removed (it has no default).\n */\n public removeCatalogViewHeaders(): void {\n if (this.viewIdDefault) {\n this.headerAppliers.forEach((setFn) => {\n setFn(this.viewIdHeaderKey, this.viewIdDefault);\n });\n } else {\n this.headerRemovers.forEach((removeFn) => {\n removeFn(this.viewIdHeaderKey);\n });\n }\n\n this.headerRemovers.forEach((removeFn) => {\n removeFn(this.accessTokenHeaderKey);\n });\n\n this.catalogViewHeaderSet = false;\n }\n\n /**\n * Checks if catalog-view headers are currently set\n * @returns true if the view-id header is set, false otherwise\n */\n public isCatalogViewHeaderSet(): boolean {\n return this.catalogViewHeaderSet;\n }\n}\n\nlet _catalogViewHeaderManager: CatalogViewHeaderManager | null = null;\n\n/**\n * Gets the singleton instance of CatalogViewHeaderManager\n * @returns The CatalogViewHeaderManager instance\n */\nexport const getCatalogViewHeaderManager = () => {\n if (!_catalogViewHeaderManager) {\n _catalogViewHeaderManager = new CatalogViewHeaderManager();\n }\n return _catalogViewHeaderManager;\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { COMPANY_FRAGMENT, CUSTOMER_FRAGMENT } from '@/company-switcher/api/fragments';\n\nexport const GET_CUSTOMER_COMPANY_CONTEXT = /* GraphQL */ `\n query GET_CUSTOMER_COMPANIES($pageSize: Int) {\n customer {\n ...CUSTOMER_FRAGMENT\n }\n company {\n ...COMPANY_FRAGMENT\n }\n customerGroup {\n uid\n }\n }\n\n ${CUSTOMER_FRAGMENT}\n ${COMPANY_FRAGMENT}\n`;\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nexport const GET_CUSTOMER_GROUP_CONTEXT = `\n query GET_CUSTOMER_GROUP {\n customerGroup {\n uid\n }\n }\n`;\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2026 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\n/**\n * Isolated query for the company-scoped catalog view context.\n *\n * This is intentionally a self-contained operation (NOT part of\n * COMPANY_FRAGMENT). The backend that serves `Company.catalogViewContext` may\n * roll out independently from this storefront, so this field may be queried\n * against an endpoint whose schema does not yet declare it.\n */\nexport const GET_CATALOG_VIEW_CONTEXT = `\n query GET_CATALOG_VIEW_CONTEXT {\n company {\n catalogViewContext {\n catalogViewId\n accessToken\n }\n }\n }\n`;\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { fetchGraphQl, getConfig } from \"@/company-switcher/api\";\nimport type { CatalogViewContext, Company, CompanyOption, CustomerCompanyInfo, GraphQLResponse } from '@/company-switcher/types/company';\nimport { GET_CUSTOMER_COMPANY_CONTEXT } from './graphql/customerCompanyContext.graphql';\nimport { GET_CUSTOMER_GROUP_CONTEXT } from './graphql/customerGroupContext.graphql';\nimport { GET_CATALOG_VIEW_CONTEXT } from './graphql/catalogViewContext.graphql';\n\n/**\n * Minimal, widened view of a GraphQL error entry. The fetch-graphql client\n * types errors as `{ message: string; extensions: { category: string } }`, but\n * at runtime `extensions` may be absent (schema-validation errors) and may\n * carry an API Mesh `code`, so both are read optionally here.\n */\ntype GraphQlErrorLike = {\n message?: string;\n extensions?: { category?: string; code?: string };\n};\n\n/**\n * Magento GraphQL runtime error categories (`extensions.category`). Their\n * presence marks a real resolver/runtime error — NOT the unknown-field schema\n * validation error used to detect deploy-skew.\n */\nconst MAGENTO_RUNTIME_ERROR_CATEGORIES = [\n 'graphql-input',\n 'graphql-no-such-entity',\n 'graphql-authorization',\n 'graphql-authentication',\n 'graphql-already-exists',\n 'graphql-server',\n];\n\n/**\n * Matches the webonyx-generated unknown-field validation message for the\n * catalog-view field, e.g. `Cannot query field \"catalogViewContext\" on type\n * \"Company\".`. This message is English and not run through Magento's\n * translation layer, so it is stable across locales.\n */\nconst UNKNOWN_CATALOG_VIEW_FIELD_PATTERN = /cannot query field .*catalogViewContext/i;\n\nexport class CustomerCompanyContext {\n private static instance: CustomerCompanyContext;\n\n // Constants\n private readonly EMPTY_CUSTOMER_COMPANY_CONTEXT: CustomerCompanyInfo = {\n currentCompany: { id: '', name: '' },\n customerCompanies: [],\n customerGroupId: '',\n };\n\n private cache: CustomerCompanyInfo | null = null;\n\n /**\n * Get singleton instance\n */\n static getInstance(): CustomerCompanyContext {\n return CustomerCompanyContext.instance ??= new CustomerCompanyContext();\n }\n\n /**\n * Transforms a company object into a company option for UI components\n */\n private transformCompanyToOption = (company: Company): CompanyOption => ({\n text: company.name,\n value: company.id\n });\n\n /**\n * Decodes base64 string and returns SHA1 hash\n */\n private async processCustomerGroupId(base64String: string): Promise<string> {\n const decoded = Uint8Array.from(atob(base64String), c => c.charCodeAt(0));\n const hashBuffer = await crypto.subtle.digest('SHA-1', decoded);\n return Array.from(new Uint8Array(hashBuffer)).map(b => b.toString(16).padStart(2, '0')).join('');\n }\n\n /**\n * Checks if the user is authenticated by verifying the Authorization header\n */\n private isUserAuthenticated(): boolean {\n return Boolean(getConfig().fetchGraphQlHeaders?.Authorization);\n }\n\n resetCache(): void {\n this.cache = null;\n }\n\n /**\n * Fetches and updates only the customer group information in the cache\n * \n * @returns Promise containing the updated customer group ID\n * @throws Will not throw errors - returns null on failure\n */\n async updateCustomerGroup(): Promise<string | null> {\n if (!this.isUserAuthenticated()) {\n return null;\n }\n\n try {\n const response = await fetchGraphQl<{ customerGroup: { uid: string } }>(GET_CUSTOMER_GROUP_CONTEXT);\n if (response.errors) {\n return null;\n }\n const customerGroupId = await this.processCustomerGroupId(response.data.customerGroup.uid);\n if (this.cache) {\n this.cache.customerGroupId = customerGroupId;\n }\n return customerGroupId;\n } catch (e) {\n console.error(e)\n return null;\n }\n }\n\n /**\n * Fetches the company-scoped catalog view context in an ISOLATED GraphQL\n * operation, deliberately separate from the shared company query.\n *\n * Robust against cases where feature is not yet deployed on target backend:\n * an unknown-field schema error is treated as the expected \"feature absent\"\n * (deploy-skew) case and skipped silently, while a real/transient error is\n * surfaced loudly (still returning null, as there is no UI to render).\n *\n * @returns Promise resolving to the catalog view context, or null on any failure\n * @throws Will not throw errors - returns null on failure\n */\n async getCatalogViewContext(): Promise<CatalogViewContext | null> {\n if (!this.isUserAuthenticated()) {\n return null;\n }\n\n try {\n const response = await fetchGraphQl<{ company: { catalogViewContext: CatalogViewContext | null } | null }>(GET_CATALOG_VIEW_CONTEXT);\n if (response.errors?.length) {\n // The `catalogViewContext` field may roll out independently from this\n // storefront, so it can be absent from the backend schema. Distinguish\n // that expected deploy-skew case (skip silently) from a real error.\n if (this.isCatalogViewFieldAbsent(response.errors as GraphQlErrorLike[])) {\n console.debug('Catalog view context field not available on backend; skipping view headers.', response.errors);\n } else {\n // A real/transient error (auth, server, etc.). Still no UI to render,\n // so return null, but log loudly so it is NOT silently mistaken for\n // the \"feature absent\" deploy-skew case.\n console.error('Catalog view context request returned errors; skipping view headers.', response.errors);\n }\n return null;\n }\n return response.data?.company?.catalogViewContext ?? null;\n } catch (e) {\n console.error(e);\n return null;\n }\n }\n\n /**\n * Decides whether a GraphQL error array represents the expected \"feature not\n * deployed\" case — an unknown-field SCHEMA VALIDATION error for\n * `catalogViewContext` — versus a real/transient error that must not be\n * silently swallowed as deploy-skew.\n *\n * The unknown-field case is a pre-execution validation error, so it carries\n * NO Magento runtime `extensions.category` (`graphql-*`); its only signal is\n * the webonyx-generated English message `Cannot query field\n * \"catalogViewContext\" ...` (or, via API Mesh, a `GRAPHQL_VALIDATION_FAILED`\n * code). We treat the batch as \"feature absent\" only when NO error carries a\n * real Magento runtime category AND at least one error matches the\n * unknown-field signature for our field.\n *\n * `extensions` is typed as non-optional by the fetch-graphql client but is\n * `undefined` for validation errors, so every access is null-guarded.\n *\n * NOTE: an API Mesh in front of Commerce can rewrite both the message and the\n * extensions, so this remains a best-effort heuristic, not a hard contract.\n */\n private isCatalogViewFieldAbsent(errors: GraphQlErrorLike[]): boolean {\n const hasRealRuntimeCategory = errors.some((error) =>\n MAGENTO_RUNTIME_ERROR_CATEGORIES.includes(error?.extensions?.category ?? '')\n );\n if (hasRealRuntimeCategory) {\n return false;\n }\n\n return errors.some(\n (error) =>\n UNKNOWN_CATALOG_VIEW_FIELD_PATTERN.test(error?.message ?? '') ||\n error?.extensions?.code === 'GRAPHQL_VALIDATION_FAILED'\n );\n }\n\n /**\n * Fetches customer company information including the current company and all available companies\n *\n * @returns Promise containing current company and list of available companies\n * @throws Will not throw errors - returns empty data on failure\n */\n async getCustomerCompanyInfo(pageSize = 100): Promise<CustomerCompanyInfo> {\n // Return cached data if available\n if (this.cache) {\n return this.cache;\n }\n\n // Return empty data if user is not authenticated\n if (!this.isUserAuthenticated()) {\n return this.EMPTY_CUSTOMER_COMPANY_CONTEXT;\n }\n\n try {\n // Fetch company data from GraphQL API\n const response = (await fetchGraphQl<GraphQLResponse>(GET_CUSTOMER_COMPANY_CONTEXT, { variables: { pageSize } }));\n if (response.errors) {\n return this.EMPTY_CUSTOMER_COMPANY_CONTEXT;\n }\n\n const data = response.data;\n const customerGroup = await this.processCustomerGroupId(response.data.customerGroup.uid);\n // Whitelist approach: only allow APPROVED and BLOCKED companies\n // BLOCKED companies allow users to log in and view but not perform actions\n const activeCompanies = data.customer.companies.items.filter(\n company => company.status === 'APPROVED' || company.status === 'BLOCKED'\n );\n const customerCompanies = activeCompanies.map(this.transformCompanyToOption);\n\n this.cache = {\n currentCompany: data.company,\n customerCompanies,\n customerGroupId: customerGroup\n }\n return this.cache;\n } catch (e) {\n console.error(e);\n return this.EMPTY_CUSTOMER_COMPANY_CONTEXT;\n }\n }\n}\n\nexport const getCustomerCompanyInfo = (pageSize = 100): Promise<CustomerCompanyInfo> => {\n return CustomerCompanyContext.getInstance().getCustomerCompanyInfo(pageSize);\n};\n\nexport const updateCustomerGroup = (): Promise<string | null> => {\n return CustomerCompanyContext.getInstance().updateCustomerGroup();\n};\n\nexport const getCatalogViewContext = (): Promise<CatalogViewContext | null> => {\n return CustomerCompanyContext.getInstance().getCatalogViewContext();\n};","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport type { FetchGraphQL } from '@adobe-commerce/fetch-graphql';\nimport { Initializer } from '@adobe-commerce/elsie/lib';\nimport { Lang } from '@adobe-commerce/elsie/i18n';\nimport { getCompanyHeaderManager } from '@/company-switcher/api/setCompanyHeaders/setCompanyHeaders';\nimport { getGroupHeaderManager } from '@/company-switcher/api/setGroupHeaders/setGroupHeaders';\nimport { getCatalogViewHeaderManager } from '@/company-switcher/api/setCatalogViewHeaders/setCatalogViewHeaders';\nimport { getCustomerCompanyInfo, getCatalogViewContext } from '@/company-switcher/api/customerCompanyContext/customerCompanyContext';\nimport { events } from '@adobe-commerce/event-bus';\n\n/**\n * Configuration properties for the company switcher initialization\n */\ninterface ConfigProps {\n /** Optional language definitions for internationalization */\n langDefinitions?: Lang;\n /** HTTP header name for company identification */\n companyHeader: string;\n /** HTTP header name for customer group identification */\n customerGroupHeader: string;\n /** Session storage key for persisting company context */\n companySessionStorageKey: string;\n /** Session storage key for persisting group context */\n groupSessionStorageKey: string;\n /** GraphQL modules that will have company headers applied */\n fetchGraphQlModules: FetchGraphQL[];\n /** GraphQL modules that will have group headers applied */\n groupGraphQlModules: FetchGraphQL[];\n /** GraphQL modules that will have catalog-view headers applied */\n catalogViewGraphQlModules: FetchGraphQL[];\n /** HTTP header name for the catalog view id */\n catalogViewHeader: string;\n /** HTTP header name for the catalog view access token */\n catalogViewAccessTokenHeader: string;\n /**\n * Default/public catalog view id the view-id header is reset to on\n * clear/logout. Leave empty to remove the header on clear instead.\n */\n catalogViewDefault: string;\n}\n\n/**\n * Re-fetches the company-scoped catalog view context and (re)applies the view\n * headers, or clears them when there is no company. This is the single place\n * catalog-view headers are refreshed in response to a company-context change.\n *\n * It runs from the `companyContext/changed` listener (registered in `init`) for\n * every path that emits that event — company switch, multi-company login, and\n * externally emitted context changes — which fires only AFTER the company/group\n * headers are set, preserving the \"fetch after company headers\" ordering. It is\n * also called inline on the internal paths that never emit the event\n * (single-company login and stored-company restore).\n *\n * Any failure resolves to null, which clears the view headers (reset-to-default\n * per {@link CatalogViewHeaderManager}) while leaving company/group intact.\n *\n * @param companyId - The active company id, or null/empty to clear the headers\n */\nconst applyCatalogViewHeaders = async (companyId: string | null): Promise<void> => {\n if (!companyId) {\n getCatalogViewHeaderManager().removeCatalogViewHeaders();\n return;\n }\n const catalogViewContext = await getCatalogViewContext();\n getCatalogViewHeaderManager().setCatalogViewHeaders(catalogViewContext);\n};\n\n/**\n * Initializer for the company switcher drop-in.\n * Configures headers, storage, and GraphQL modules for company management.\n */\nexport const initialize = new Initializer<ConfigProps>({\n init: async (config) => {\n const defaultConfig = {\n fetchGraphQlModules: [],\n groupGraphQlModules: [],\n catalogViewGraphQlModules: [],\n companyHeader: 'X-Adobe-Company',\n customerGroupHeader: 'Magento-Customer-Group',\n catalogViewHeader: 'AC-View-Id',\n catalogViewAccessTokenHeader: 'AC-Catalog-View-Access-Token',\n catalogViewDefault: '',\n companySessionStorageKey: 'DROPIN__COMPANYSWITCHER__COMPANY__CONTEXT',\n groupSessionStorageKey: 'DROPIN__COMPANYSWITCHER__GROUP__CONTEXT'\n };\n initialize.config.setConfig({ ...defaultConfig, ...config });\n\n const groupId = sessionStorage.getItem(initialize.config.getConfig().groupSessionStorageKey);\n const companyId = sessionStorage.getItem(initialize.config.getConfig().companySessionStorageKey);\n if (companyId && !getCompanyHeaderManager().isCompanyHeaderSet()) {\n getCompanyHeaderManager().setCompanyHeaders(companyId);\n events.emit('companyContext/changed', companyId);\n }\n if (groupId && !getGroupHeaderManager().isGroupHeaderSet()) {\n getGroupHeaderManager().setGroupHeaders(groupId);\n }\n\n // Single refresh point for company-context changes, including those emitted\n // by EXTERNAL drop-ins / host code (see applyCatalogViewHeaders above).\n // Registered AFTER the initial restore emit above so that emit — handled\n // inline on the stored-restore branch below — does not double-trigger it.\n events.on('companyContext/changed', async (companyId: string | null) => {\n await applyCatalogViewHeaders(companyId);\n });\n\n events.on('authenticated', async (authenticated: boolean) => {\n const config = initialize.config.getConfig();\n if (!authenticated) {\n sessionStorage.removeItem(config.companySessionStorageKey);\n sessionStorage.removeItem(config.groupSessionStorageKey);\n getCompanyHeaderManager().removeCompanyHeaders();\n getGroupHeaderManager().removeGroupHeaders();\n // Clear the view headers inline for our own logout; the emit below also\n // notifies external listeners (and re-clears via the listener above — an\n // idempotent no-op, no fetch).\n getCatalogViewHeaderManager().removeCatalogViewHeaders();\n events.emit('companyContext/changed', null);\n } else {\n const storedCompanyId = sessionStorage.getItem(config.companySessionStorageKey);\n if (storedCompanyId || getCompanyHeaderManager().isCompanyHeaderSet()) {\n // Company/group headers are already restored from sessionStorage on a\n // page reload, so the company re-fetch and re-emit are intentionally\n // short-circuited — and this branch does NOT emit\n // companyContext/changed, so the listener above will not refresh the\n // view headers. View headers are never rehydrated from storage, so\n // re-fetch and (re)apply them inline here.\n if (storedCompanyId) {\n await applyCatalogViewHeaders(storedCompanyId);\n }\n return;\n }\n const companyInfo = await getCustomerCompanyInfo();\n\n if (companyInfo.customerCompanies.length < 2) {\n // Single-company users never emit companyContext/changed, so the\n // listener above will not refresh their view headers — apply inline.\n if (companyInfo.currentCompany?.id) {\n await applyCatalogViewHeaders(companyInfo.currentCompany.id);\n }\n return;\n }\n\n const currentCompanyId = companyInfo.currentCompany.id;\n const groupId = companyInfo.customerGroupId;\n getCompanyHeaderManager().setCompanyHeaders(currentCompanyId);\n getGroupHeaderManager().setGroupHeaders(groupId);\n sessionStorage.setItem(config.companySessionStorageKey, currentCompanyId);\n sessionStorage.setItem(config.groupSessionStorageKey, groupId);\n // View headers are (re)applied by the companyContext/changed listener\n // above, which fires AFTER the company/group headers set here — a single\n // isolated fetch, no inline duplicate.\n events.emit('companyContext/changed', currentCompanyId);\n }\n }, { eager: true });\n },\n listeners: () => []\n});\n\n/**\n * Configuration object for getting and setting company switcher configuration.\n * Provides methods to access and update the current configuration.\n */\nexport const config = initialize.config;\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { FetchGraphQL } from '@adobe-commerce/fetch-graphql';\n\n/**\n * GraphQL client methods for making API requests.\n * Provides methods to configure endpoints, headers, and execute GraphQL queries.\n */\nexport const {\n /** Sets the GraphQL endpoint URL */\n setEndpoint,\n /** Sets a single GraphQL header */\n setFetchGraphQlHeader,\n /** Removes a GraphQL header */\n removeFetchGraphQlHeader,\n /** Sets multiple GraphQL headers at once */\n setFetchGraphQlHeaders,\n /** Executes a GraphQL query or mutation */\n fetchGraphQl,\n /** Gets the current configuration */\n getConfig,\n} = new FetchGraphQL().getMethods();\n"],"names":["CompanyHeaderManager","__publicField","config","headerKey","modules","module","key","value","companyId","setFn","removeFn","_companyHeaderManager","getCompanyHeaderManager","GroupHeaderManager","groupId","_groupHeaderManager","getGroupHeaderManager","CatalogViewHeaderManager","defaultViewId","context","token","_catalogViewHeaderManager","getCatalogViewHeaderManager","GET_CUSTOMER_COMPANY_CONTEXT","CUSTOMER_FRAGMENT","COMPANY_FRAGMENT","GET_CUSTOMER_GROUP_CONTEXT","GET_CATALOG_VIEW_CONTEXT","MAGENTO_RUNTIME_ERROR_CATEGORIES","UNKNOWN_CATALOG_VIEW_FIELD_PATTERN","_CustomerCompanyContext","company","base64String","decoded","c","hashBuffer","b","_a","getConfig","response","fetchGraphQl","customerGroupId","_c","_b","e","errors","error","pageSize","data","customerGroup","customerCompanies","CustomerCompanyContext","getCustomerCompanyInfo","updateCustomerGroup","getCatalogViewContext","applyCatalogViewHeaders","catalogViewContext","initialize","Initializer","defaultConfig","events","authenticated","storedCompanyId","companyInfo","currentCompanyId","setEndpoint","setFetchGraphQlHeader","removeFetchGraphQlHeader","setFetchGraphQlHeaders","FetchGraphQL"],"mappings":"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"}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* from Adobe.
|
|
16
16
|
*******************************************************************/
|
|
17
17
|
import { HTMLAttributes } from 'preact/compat';
|
|
18
|
-
import { Container } from '
|
|
18
|
+
import { Container } from '../../../node_modules/@dropins/tools/src/lib';
|
|
19
19
|
import { Company } from '../../types/company';
|
|
20
20
|
export interface CompanySwitcherProps extends HTMLAttributes<HTMLDivElement> {
|
|
21
21
|
/** Custom aria-label for the picker */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CompanySwitcher.js","sources":["/@dropins/storefront-company-switcher/src/hooks/useCompanyData.ts","/@dropins/storefront-company-switcher/src/containers/CompanySwitcher/CompanySwitcher.tsx"],"sourcesContent":["/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { useState, useCallback, useEffect } from 'preact/hooks';\nimport { events } from '@adobe-commerce/event-bus';\nimport { CustomerCompanyContext, updateCustomerGroup } from '@/company-switcher/api/customerCompanyContext';\nimport type { CompanyOption, CustomerCompanyInfo, UseCompanyDataProps, UseCompanyDataReturn } from '@/company-switcher/types/company';\nimport { config } from '@/company-switcher/api/initialize';\nimport { getGroupHeaderManager } from '@/company-switcher/api/setGroupHeaders';\nimport { getCompanyHeaderManager } from '@/company-switcher/api/setCompanyHeaders';\n\n/**\n * Custom hook that manages company data fetching and state management\n * @returns {UseCompanyDataReturn} Company data and handlers\n */\nexport const useCompanyData = ({ onCompanyChange, pageSize = 100 }: UseCompanyDataProps = {}): UseCompanyDataReturn => {\n const [companies, setCompanies] = useState<CompanyOption[]>([]);\n const [currentCompany, setCurrentCompany] = useState<CompanyOption>({ text: '', value: '' });\n\n\n /**\n * Loads company information from the API and updates state\n */\n const loadCompanyData = useCallback(async (): Promise<void> => {\n try {\n const customerCompanyContext = CustomerCompanyContext.getInstance();\n const companyInfo: CustomerCompanyInfo = await customerCompanyContext.getCustomerCompanyInfo(pageSize);\n setCompanies(companyInfo.customerCompanies);\n \n if (companyInfo.currentCompany?.name && companyInfo.currentCompany?.id) {\n setCurrentCompany({\n text: companyInfo.currentCompany.name, \n value: companyInfo.currentCompany.id\n });\n }\n } catch (err) {\n console.error('Failed to load company data:', err);\n }\n }, [pageSize]);\n\n /**\n * Handles company selection change\n */\n const handleCompanyChange = useCallback(async (event: Event): Promise<void> => {\n const target = event.target as HTMLSelectElement;\n const companyId = target.value;\n \n // Update local state\n const selectedCompany = companies.find(c => c.value === companyId);\n if (selectedCompany) {\n setCurrentCompany(selectedCompany);\n }\n \n getCompanyHeaderManager().setCompanyHeaders(companyId);\n if (companyId) {\n sessionStorage.setItem(config.getConfig().companySessionStorageKey, companyId);\n } else {\n sessionStorage.removeItem(config.getConfig().companySessionStorageKey);\n }\n const groupId = await updateCustomerGroup();\n getGroupHeaderManager().setGroupHeaders(groupId);\n if (groupId) {\n sessionStorage.setItem(config.getConfig().groupSessionStorageKey, groupId);\n } else {\n sessionStorage.removeItem(config.getConfig().groupSessionStorageKey);\n }\n\n onCompanyChange?.({ id: companyId, name: selectedCompany?.text || '' });\n\n events.emit('companyContext/changed', companyId);\n }, [companies, onCompanyChange]);\n\n /**\n * Clears company context\n */\n const clearCompanyContext = useCallback((): void => {\n const customerCompanyContext = CustomerCompanyContext.getInstance();\n customerCompanyContext.resetCache();\n setCompanies([]);\n setCurrentCompany({ text: '', value: '' });\n }, []);\n\n /**\n * Handles authentication state changes\n */\n const handleAuthenticationChange = useCallback((authenticated: boolean) => {\n if (authenticated) {\n loadCompanyData();\n } else {\n clearCompanyContext();\n }\n }, [loadCompanyData, clearCompanyContext]);\n\n /**\n * Handles company context restoration\n */\n const handleCompanyContextRestored = useCallback((companyId: string | null) => {\n if (!companyId) {\n clearCompanyContext();\n return;\n }\n // Store the company ID to be restored when companies are loaded\n setCompanies(prevCompanies => {\n const restoredCompany = prevCompanies.find(company => company.value === companyId);\n if (restoredCompany) {\n setCurrentCompany(restoredCompany);\n }\n return prevCompanies;\n });\n }, [clearCompanyContext, setCompanies, setCurrentCompany]);\n\n /**\n * Handles company updated event\n */\n const handleCompanyUpdated = useCallback((eventData: { company: { id: string; name: string; } }) => {\n const { company } = eventData;\n\n setCompanies(prevCompanies => {\n const companyIndex = prevCompanies.findIndex(c => c.value === company.id);\n if (companyIndex === -1) {\n return prevCompanies;\n }\n return prevCompanies.map((c, i) =>\n i === companyIndex ? { ...c, text: company.name } : c\n );\n });\n \n setCurrentCompany({\n text: company.name,\n value: company.id\n });\n }, []);\n\n // Set up event listeners\n useEffect(() => {\n const unsubscribeAuth = events.on('authenticated', handleAuthenticationChange, { eager: true });\n const unsubscribeRestore = events.on('companyContext/changed', handleCompanyContextRestored, { eager: true });\n const unsubscribeCompanyUpdated = events.on('company/updated', handleCompanyUpdated);\n \n return () => {\n unsubscribeAuth?.off?.();\n unsubscribeRestore?.off?.();\n unsubscribeCompanyUpdated?.off?.();\n };\n }, [handleAuthenticationChange, handleCompanyContextRestored, handleCompanyUpdated]);\n\n return {\n companies,\n currentCompany,\n handleCompanyChange\n };\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n \nimport { HTMLAttributes } from 'preact/compat';\nimport { useMemo, useState, useEffect } from 'preact/hooks';\nimport { Container } from '@adobe-commerce/elsie/lib';\nimport { Picker } from '@adobe-commerce/elsie/components';\nimport { events } from '@adobe-commerce/event-bus';\nimport { useCompanyData } from '@/company-switcher/hooks/useCompanyData';\nimport { Company } from '@/company-switcher/types/company';\n\nexport interface CompanySwitcherProps extends HTMLAttributes<HTMLDivElement> {\n /** Custom aria-label for the picker */\n ariaLabel?: string;\n /** Callback function to be called when the company changes */\n onCompanyChange?: (company: Company) => void;\n /** Maximum number of companies to fetch for the picker */\n size?: number;\n}\n\n/**\n * CompanySwitcher component allows users to switch between companies they have access to.\n * It only renders when a user has access to multiple companies.\n * This is a presentational component that uses the useCompanyData hook for all business logic.\n */\nexport const CompanySwitcher: Container<CompanySwitcherProps> = ({\n ariaLabel,\n onCompanyChange,\n size = 100,\n ...props\n}) => {\n const { companies, currentCompany, handleCompanyChange } = useCompanyData({ onCompanyChange, pageSize: size });\n const [isVisible, setIsVisible] = useState(true);\n\n // Memoize the companies array to prevent unnecessary re-renders\n const memoizedCompanies = useMemo(() => companies, [companies]);\n\n // Listen for checkout/initialized and checkout/updated events to hide the picker\n useEffect(() => {\n const hidePickerHandler = () => {\n setIsVisible(false);\n };\n\n const unsubscribeInitialized = events.on('checkout/initialized', hidePickerHandler);\n const unsubscribeUpdated = events.on('checkout/updated', hidePickerHandler);\n\n return () => {\n unsubscribeInitialized?.off();\n unsubscribeUpdated?.off();\n };\n }, []);\n\n // Only render if user has access to multiple companies and picker is visible\n if (companies.length < 2 || !isVisible) {\n return null;\n }\n\n return (\n <div {...props}>\n <Picker \n options={memoizedCompanies} \n value={currentCompany.value} \n onChange={handleCompanyChange}\n aria-label={ariaLabel || 'Select company'}\n aria-describedby=\"company-switcher-description\"\n />\n </div>\n );\n};\n"],"names":["useCompanyData","onCompanyChange","pageSize","companies","setCompanies","useState","currentCompany","setCurrentCompany","loadCompanyData","useCallback","companyInfo","CustomerCompanyContext","_a","_b","err","handleCompanyChange","event","companyId","selectedCompany","c","getCompanyHeaderManager","config","groupId","updateCustomerGroup","getGroupHeaderManager","events","clearCompanyContext","handleAuthenticationChange","authenticated","handleCompanyContextRestored","prevCompanies","restoredCompany","company","handleCompanyUpdated","eventData","companyIndex","i","useEffect","unsubscribeAuth","unsubscribeRestore","unsubscribeCompanyUpdated","_c","CompanySwitcher","ariaLabel","size","props","isVisible","setIsVisible","memoizedCompanies","useMemo","hidePickerHandler","unsubscribeInitialized","unsubscribeUpdated","jsx","Picker"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CompanySwitcher.js","sources":["/@dropins/storefront-company-switcher/src/hooks/useCompanyData.ts","/@dropins/storefront-company-switcher/src/containers/CompanySwitcher/CompanySwitcher.tsx"],"sourcesContent":["/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { useState, useCallback, useEffect } from 'preact/hooks';\nimport { events } from '@adobe-commerce/event-bus';\nimport { CustomerCompanyContext, updateCustomerGroup } from '@/company-switcher/api/customerCompanyContext';\nimport type { CompanyOption, CustomerCompanyInfo, UseCompanyDataProps, UseCompanyDataReturn } from '@/company-switcher/types/company';\nimport { config } from '@/company-switcher/api/initialize';\nimport { getGroupHeaderManager } from '@/company-switcher/api/setGroupHeaders';\nimport { getCompanyHeaderManager } from '@/company-switcher/api/setCompanyHeaders';\n\n/**\n * Custom hook that manages company data fetching and state management\n * @returns {UseCompanyDataReturn} Company data and handlers\n */\nexport const useCompanyData = ({ onCompanyChange, pageSize = 100 }: UseCompanyDataProps = {}): UseCompanyDataReturn => {\n const [companies, setCompanies] = useState<CompanyOption[]>([]);\n const [currentCompany, setCurrentCompany] = useState<CompanyOption>({ text: '', value: '' });\n\n\n /**\n * Loads company information from the API and updates state\n */\n const loadCompanyData = useCallback(async (): Promise<void> => {\n try {\n const customerCompanyContext = CustomerCompanyContext.getInstance();\n const companyInfo: CustomerCompanyInfo = await customerCompanyContext.getCustomerCompanyInfo(pageSize);\n setCompanies(companyInfo.customerCompanies);\n \n if (companyInfo.currentCompany?.name && companyInfo.currentCompany?.id) {\n setCurrentCompany({\n text: companyInfo.currentCompany.name, \n value: companyInfo.currentCompany.id\n });\n }\n } catch (err) {\n console.error('Failed to load company data:', err);\n }\n }, [pageSize]);\n\n /**\n * Handles company selection change\n */\n const handleCompanyChange = useCallback(async (event: Event): Promise<void> => {\n const target = event.target as HTMLSelectElement;\n const companyId = target.value;\n \n // Update local state\n const selectedCompany = companies.find(c => c.value === companyId);\n if (selectedCompany) {\n setCurrentCompany(selectedCompany);\n }\n \n getCompanyHeaderManager().setCompanyHeaders(companyId);\n if (companyId) {\n sessionStorage.setItem(config.getConfig().companySessionStorageKey, companyId);\n } else {\n sessionStorage.removeItem(config.getConfig().companySessionStorageKey);\n }\n const groupId = await updateCustomerGroup();\n getGroupHeaderManager().setGroupHeaders(groupId);\n if (groupId) {\n sessionStorage.setItem(config.getConfig().groupSessionStorageKey, groupId);\n } else {\n sessionStorage.removeItem(config.getConfig().groupSessionStorageKey);\n }\n\n onCompanyChange?.({ id: companyId, name: selectedCompany?.text || '' });\n\n // Catalog-view headers are refreshed by the companyContext/changed listener\n // in `initialize`, which fires after the company/group headers set above\n // (the backend resolver keys off them) — this emit is the single trigger.\n events.emit('companyContext/changed', companyId);\n }, [companies, onCompanyChange]);\n\n /**\n * Clears company context\n */\n const clearCompanyContext = useCallback((): void => {\n const customerCompanyContext = CustomerCompanyContext.getInstance();\n customerCompanyContext.resetCache();\n setCompanies([]);\n setCurrentCompany({ text: '', value: '' });\n }, []);\n\n /**\n * Handles authentication state changes\n */\n const handleAuthenticationChange = useCallback((authenticated: boolean) => {\n if (authenticated) {\n loadCompanyData();\n } else {\n clearCompanyContext();\n }\n }, [loadCompanyData, clearCompanyContext]);\n\n /**\n * Handles company context restoration\n */\n const handleCompanyContextRestored = useCallback((companyId: string | null) => {\n if (!companyId) {\n clearCompanyContext();\n return;\n }\n // Store the company ID to be restored when companies are loaded\n setCompanies(prevCompanies => {\n const restoredCompany = prevCompanies.find(company => company.value === companyId);\n if (restoredCompany) {\n setCurrentCompany(restoredCompany);\n }\n return prevCompanies;\n });\n }, [clearCompanyContext, setCompanies, setCurrentCompany]);\n\n /**\n * Handles company updated event\n */\n const handleCompanyUpdated = useCallback((eventData: { company: { id: string; name: string; } }) => {\n const { company } = eventData;\n\n setCompanies(prevCompanies => {\n const companyIndex = prevCompanies.findIndex(c => c.value === company.id);\n if (companyIndex === -1) {\n return prevCompanies;\n }\n return prevCompanies.map((c, i) =>\n i === companyIndex ? { ...c, text: company.name } : c\n );\n });\n \n setCurrentCompany({\n text: company.name,\n value: company.id\n });\n }, []);\n\n // Set up event listeners\n useEffect(() => {\n const unsubscribeAuth = events.on('authenticated', handleAuthenticationChange, { eager: true });\n const unsubscribeRestore = events.on('companyContext/changed', handleCompanyContextRestored, { eager: true });\n const unsubscribeCompanyUpdated = events.on('company/updated', handleCompanyUpdated);\n \n return () => {\n unsubscribeAuth?.off?.();\n unsubscribeRestore?.off?.();\n unsubscribeCompanyUpdated?.off?.();\n };\n }, [handleAuthenticationChange, handleCompanyContextRestored, handleCompanyUpdated]);\n\n return {\n companies,\n currentCompany,\n handleCompanyChange\n };\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n \nimport { HTMLAttributes } from 'preact/compat';\nimport { useMemo, useState, useEffect } from 'preact/hooks';\nimport { Container } from '@adobe-commerce/elsie/lib';\nimport { Picker } from '@adobe-commerce/elsie/components';\nimport { events } from '@adobe-commerce/event-bus';\nimport { useCompanyData } from '@/company-switcher/hooks/useCompanyData';\nimport { Company } from '@/company-switcher/types/company';\n\nexport interface CompanySwitcherProps extends HTMLAttributes<HTMLDivElement> {\n /** Custom aria-label for the picker */\n ariaLabel?: string;\n /** Callback function to be called when the company changes */\n onCompanyChange?: (company: Company) => void;\n /** Maximum number of companies to fetch for the picker */\n size?: number;\n}\n\n/**\n * CompanySwitcher component allows users to switch between companies they have access to.\n * It only renders when a user has access to multiple companies.\n * This is a presentational component that uses the useCompanyData hook for all business logic.\n */\nexport const CompanySwitcher: Container<CompanySwitcherProps> = ({\n ariaLabel,\n onCompanyChange,\n size = 100,\n ...props\n}) => {\n const { companies, currentCompany, handleCompanyChange } = useCompanyData({ onCompanyChange, pageSize: size });\n const [isVisible, setIsVisible] = useState(true);\n\n // Memoize the companies array to prevent unnecessary re-renders\n const memoizedCompanies = useMemo(() => companies, [companies]);\n\n // Listen for checkout/initialized and checkout/updated events to hide the picker\n useEffect(() => {\n const hidePickerHandler = () => {\n setIsVisible(false);\n };\n\n const unsubscribeInitialized = events.on('checkout/initialized', hidePickerHandler);\n const unsubscribeUpdated = events.on('checkout/updated', hidePickerHandler);\n\n return () => {\n unsubscribeInitialized?.off();\n unsubscribeUpdated?.off();\n };\n }, []);\n\n // Only render if user has access to multiple companies and picker is visible\n if (companies.length < 2 || !isVisible) {\n return null;\n }\n\n return (\n <div {...props}>\n <Picker \n options={memoizedCompanies} \n value={currentCompany.value} \n onChange={handleCompanyChange}\n aria-label={ariaLabel || 'Select company'}\n aria-describedby=\"company-switcher-description\"\n />\n </div>\n );\n};\n"],"names":["useCompanyData","onCompanyChange","pageSize","companies","setCompanies","useState","currentCompany","setCurrentCompany","loadCompanyData","useCallback","companyInfo","CustomerCompanyContext","_a","_b","err","handleCompanyChange","event","companyId","selectedCompany","c","getCompanyHeaderManager","config","groupId","updateCustomerGroup","getGroupHeaderManager","events","clearCompanyContext","handleAuthenticationChange","authenticated","handleCompanyContextRestored","prevCompanies","restoredCompany","company","handleCompanyUpdated","eventData","companyIndex","i","useEffect","unsubscribeAuth","unsubscribeRestore","unsubscribeCompanyUpdated","_c","CompanySwitcher","ariaLabel","size","props","isVisible","setIsVisible","memoizedCompanies","useMemo","hidePickerHandler","unsubscribeInitialized","unsubscribeUpdated","jsx","Picker"],"mappings":"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"}
|
package/package.json
CHANGED
package/types/company.d.ts
CHANGED
|
@@ -56,6 +56,17 @@ export interface UseCompanyDataReturn {
|
|
|
56
56
|
currentCompany: CompanyOption;
|
|
57
57
|
handleCompanyChange: (event: Event) => Promise<void>;
|
|
58
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Company-scoped catalog view context served by the backend via
|
|
61
|
+
* `Company.catalogViewContext`.
|
|
62
|
+
*
|
|
63
|
+
* `accessToken` is null until a restricted access key is provisioned/set up
|
|
64
|
+
* on the target environment.
|
|
65
|
+
*/
|
|
66
|
+
export interface CatalogViewContext {
|
|
67
|
+
catalogViewId: string;
|
|
68
|
+
accessToken: string | null;
|
|
69
|
+
}
|
|
59
70
|
/**
|
|
60
71
|
* GraphQL response wrapper
|
|
61
72
|
*/
|