@coveo/shopify 1.6.1-pre.fda43fc695 → 1.7.0-pre.153636d7cb
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/README.md +46 -0
- package/dist/constants.esm.js +23 -0
- package/dist/headless/commerce.d.ts +2 -2
- package/dist/headless/commerce.esm.js +67 -3
- package/dist/headless/commerce.js +3 -3
- package/dist/headless/search.d.ts +2 -1
- package/dist/headless/search.esm.js +67 -3
- package/dist/headless/search.js +3 -2
- package/dist/headless.esm.js +71 -3
- package/dist/types.d.ts +4 -4
- package/dist/utilities/app-proxy.d.ts +4 -3
- package/dist/utilities/app-proxy.js +12 -2
- package/dist/utilities/index.d.ts +3 -2
- package/dist/utilities/index.js +2 -1
- package/dist/utilities/init.d.ts +2 -0
- package/dist/utilities/init.js +16 -0
- package/dist/utilities/memoize.d.ts +13 -0
- package/dist/utilities/memoize.js +37 -0
- package/dist/utilities.esm.js +67 -1
- package/package.json +8 -2
package/README.md
CHANGED
|
@@ -20,6 +20,52 @@ yarn add @coveo/shopify
|
|
|
20
20
|
|
|
21
21
|
## Features
|
|
22
22
|
|
|
23
|
+
### `init`
|
|
24
|
+
|
|
25
|
+
Initializes the Coveo Shopify integration to ensure that web pixels work correctly. This function should be called on every page of your Shopify store to maintain consistent tracking and personalization.
|
|
26
|
+
|
|
27
|
+
The `init` function publishes a custom event with the configuration data that the web pixels need to function properly.
|
|
28
|
+
|
|
29
|
+
#### Parameters
|
|
30
|
+
|
|
31
|
+
- `options` (required): A `CoveoShopifyOptions` object containing:
|
|
32
|
+
- `accessToken` (required): The access token for the Coveo API.
|
|
33
|
+
- `organizationId` (required): The organization ID.
|
|
34
|
+
- `environment` (required): The environment configuration ('dev', 'stg', 'prod', etc.).
|
|
35
|
+
- `trackingId` (required): The tracking ID for analytics.
|
|
36
|
+
|
|
37
|
+
#### Returns
|
|
38
|
+
|
|
39
|
+
This function doesn't return a value but publishes a custom event that web pixels can listen to.
|
|
40
|
+
|
|
41
|
+
#### Example
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import {init} from '@coveo/shopify/utilities';
|
|
45
|
+
|
|
46
|
+
// Initialize on every page
|
|
47
|
+
init({
|
|
48
|
+
accessToken: 'your-access-token',
|
|
49
|
+
organizationId: 'your-org-id',
|
|
50
|
+
environment: 'prod',
|
|
51
|
+
trackingId: 'your-tracking-id',
|
|
52
|
+
});
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
#### Usage with App Proxy Configuration
|
|
56
|
+
|
|
57
|
+
You can combine the `init` function with `fetchAppProxyConfig` to initialize the integration:
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
import {init, fetchAppProxyConfig} from '@coveo/shopify/utilities';
|
|
61
|
+
|
|
62
|
+
const config = await fetchAppProxyConfig({
|
|
63
|
+
marketId: 'market_123432',
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
init(config);
|
|
67
|
+
```
|
|
68
|
+
|
|
23
69
|
### `fetchAppProxyConfig`
|
|
24
70
|
|
|
25
71
|
Fetches the app proxy configuration for a given Shopify market.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
*
|
|
4
|
+
* Copyright 2025 Coveo Solutions Inc.
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this file except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
// src/constants.ts
|
|
20
|
+
var COVEO_SHOPIFY_CONFIG_KEY = "coveo_shopify_config";
|
|
21
|
+
export {
|
|
22
|
+
COVEO_SHOPIFY_CONFIG_KEY
|
|
23
|
+
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { CommerceEngineOptions } from '@coveo/headless/commerce';
|
|
2
|
-
export
|
|
2
|
+
export type * from '../types';
|
|
3
3
|
export * from '@coveo/headless/commerce';
|
|
4
|
+
export * from '../constants';
|
|
4
5
|
export * from '../utilities';
|
|
5
|
-
export type { AppProxyConfig, AppProxyResponse } from '../types';
|
|
6
6
|
export interface BuildShopifyCommerceEngineOptions {
|
|
7
7
|
commerceEngineOptions: CommerceEngineOptions;
|
|
8
8
|
}
|
|
@@ -34,20 +34,82 @@ function publishCustomShopifyEvent(key, customData) {
|
|
|
34
34
|
// src/headless/commerce.ts
|
|
35
35
|
export * from "@coveo/headless/commerce";
|
|
36
36
|
|
|
37
|
+
// src/utilities/memoize.ts
|
|
38
|
+
function memoize(fn, getCacheKey) {
|
|
39
|
+
const cache = /* @__PURE__ */ new Map();
|
|
40
|
+
return {
|
|
41
|
+
fn: async (...args) => {
|
|
42
|
+
const key = getCacheKey(...args);
|
|
43
|
+
if (cache.has(key)) {
|
|
44
|
+
return cache.get(key);
|
|
45
|
+
}
|
|
46
|
+
const promise = fn(...args);
|
|
47
|
+
cache.set(key, promise);
|
|
48
|
+
try {
|
|
49
|
+
const result = await promise;
|
|
50
|
+
return result;
|
|
51
|
+
} catch (error) {
|
|
52
|
+
cache.delete(key);
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
clearCache: () => {
|
|
57
|
+
cache.clear();
|
|
58
|
+
},
|
|
59
|
+
clearCacheEntry: (...args) => {
|
|
60
|
+
const key = getCacheKey(...args);
|
|
61
|
+
cache.delete(key);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
37
66
|
// src/utilities/app-proxy.ts
|
|
67
|
+
var memoizedFetch = memoize(
|
|
68
|
+
(...args) => global.fetch(...args),
|
|
69
|
+
(url) => url
|
|
70
|
+
);
|
|
38
71
|
async function fetchAppProxyConfig({
|
|
39
72
|
appProxyUrl = "/apps/coveo",
|
|
40
73
|
marketId
|
|
41
74
|
}) {
|
|
42
|
-
const
|
|
75
|
+
const url = `${appProxyUrl}?marketId=${marketId}`;
|
|
76
|
+
const response = await memoizedFetch.fn(url);
|
|
77
|
+
if (!response.ok) {
|
|
78
|
+
memoizedFetch.clearCacheEntry(url);
|
|
79
|
+
throw new Error(
|
|
80
|
+
`Failed to fetch app proxy configuration from ${appProxyUrl} for marketId ${marketId}. Status: ${response.status}`
|
|
81
|
+
);
|
|
82
|
+
}
|
|
43
83
|
return response.json();
|
|
44
84
|
}
|
|
85
|
+
function clearAppProxyCache() {
|
|
86
|
+
memoizedFetch.clearCache();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// src/utilities/init.ts
|
|
90
|
+
import { getAnalyticsNextApiBaseUrl } from "@coveo/headless";
|
|
91
|
+
import { createRelay } from "@coveo/relay";
|
|
92
|
+
function init(options) {
|
|
93
|
+
const relay = createRelay({
|
|
94
|
+
url: getAnalyticsNextApiBaseUrl(
|
|
95
|
+
options.organizationId,
|
|
96
|
+
options.environment
|
|
97
|
+
),
|
|
98
|
+
token: options.accessToken,
|
|
99
|
+
trackingId: options.trackingId
|
|
100
|
+
});
|
|
101
|
+
const clientId = relay.getMeta("").clientId;
|
|
102
|
+
publishCustomShopifyEvent(COVEO_SHOPIFY_CONFIG_KEY, {
|
|
103
|
+
...options,
|
|
104
|
+
clientId
|
|
105
|
+
});
|
|
106
|
+
}
|
|
45
107
|
|
|
46
108
|
// src/headless/commerce.ts
|
|
47
109
|
function buildShopifyCommerceEngine({
|
|
48
110
|
commerceEngineOptions
|
|
49
111
|
}) {
|
|
50
|
-
const
|
|
112
|
+
const options = {
|
|
51
113
|
accessToken: commerceEngineOptions.configuration.accessToken,
|
|
52
114
|
organizationId: commerceEngineOptions.configuration.organizationId,
|
|
53
115
|
environment: commerceEngineOptions.configuration.environment,
|
|
@@ -56,7 +118,7 @@ function buildShopifyCommerceEngine({
|
|
|
56
118
|
const engine = buildCommerceEngine(commerceEngineOptions);
|
|
57
119
|
const clientId = engine.relay.getMeta("").clientId;
|
|
58
120
|
publishCustomShopifyEvent(COVEO_SHOPIFY_CONFIG_KEY, {
|
|
59
|
-
...
|
|
121
|
+
...options,
|
|
60
122
|
clientId
|
|
61
123
|
});
|
|
62
124
|
return engine;
|
|
@@ -64,6 +126,8 @@ function buildShopifyCommerceEngine({
|
|
|
64
126
|
export {
|
|
65
127
|
COVEO_SHOPIFY_CONFIG_KEY,
|
|
66
128
|
buildShopifyCommerceEngine,
|
|
129
|
+
clearAppProxyCache,
|
|
67
130
|
fetchAppProxyConfig,
|
|
131
|
+
init,
|
|
68
132
|
publishCustomShopifyEvent
|
|
69
133
|
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { buildCommerceEngine, } from '@coveo/headless/commerce';
|
|
2
2
|
import { COVEO_SHOPIFY_CONFIG_KEY } from '../constants';
|
|
3
3
|
import { publishCustomShopifyEvent } from '../utilities/shopify';
|
|
4
|
-
export { COVEO_SHOPIFY_CONFIG_KEY } from '../constants';
|
|
5
4
|
export * from '@coveo/headless/commerce';
|
|
5
|
+
export * from '../constants';
|
|
6
6
|
export * from '../utilities';
|
|
7
7
|
/**
|
|
8
8
|
* Builds the commerce engine for a Shopify store.
|
|
@@ -15,7 +15,7 @@ export * from '../utilities';
|
|
|
15
15
|
* @returns The constructed commerce engine instance.
|
|
16
16
|
*/
|
|
17
17
|
export function buildShopifyCommerceEngine({ commerceEngineOptions, }) {
|
|
18
|
-
const
|
|
18
|
+
const options = {
|
|
19
19
|
accessToken: commerceEngineOptions.configuration.accessToken,
|
|
20
20
|
organizationId: commerceEngineOptions.configuration.organizationId,
|
|
21
21
|
environment: commerceEngineOptions.configuration.environment,
|
|
@@ -24,7 +24,7 @@ export function buildShopifyCommerceEngine({ commerceEngineOptions, }) {
|
|
|
24
24
|
const engine = buildCommerceEngine(commerceEngineOptions);
|
|
25
25
|
const clientId = engine.relay.getMeta('').clientId;
|
|
26
26
|
publishCustomShopifyEvent(COVEO_SHOPIFY_CONFIG_KEY, {
|
|
27
|
-
...
|
|
27
|
+
...options,
|
|
28
28
|
clientId,
|
|
29
29
|
});
|
|
30
30
|
return engine;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { SearchEngineOptions } from '@coveo/headless';
|
|
2
2
|
export { COVEO_SHOPIFY_CONFIG_KEY } from '../constants';
|
|
3
|
-
export type
|
|
3
|
+
export type * from '../types';
|
|
4
4
|
export * from '@coveo/headless';
|
|
5
|
+
export * from '../constants';
|
|
5
6
|
export * from '../utilities';
|
|
6
7
|
export interface BuildShopifySearchEngineOptions {
|
|
7
8
|
searchEngineOptions: SearchEngineOptions;
|
|
@@ -32,14 +32,76 @@ function publishCustomShopifyEvent(key, customData) {
|
|
|
32
32
|
// src/headless/search.ts
|
|
33
33
|
export * from "@coveo/headless";
|
|
34
34
|
|
|
35
|
+
// src/utilities/memoize.ts
|
|
36
|
+
function memoize(fn, getCacheKey) {
|
|
37
|
+
const cache = /* @__PURE__ */ new Map();
|
|
38
|
+
return {
|
|
39
|
+
fn: async (...args) => {
|
|
40
|
+
const key = getCacheKey(...args);
|
|
41
|
+
if (cache.has(key)) {
|
|
42
|
+
return cache.get(key);
|
|
43
|
+
}
|
|
44
|
+
const promise = fn(...args);
|
|
45
|
+
cache.set(key, promise);
|
|
46
|
+
try {
|
|
47
|
+
const result = await promise;
|
|
48
|
+
return result;
|
|
49
|
+
} catch (error) {
|
|
50
|
+
cache.delete(key);
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
clearCache: () => {
|
|
55
|
+
cache.clear();
|
|
56
|
+
},
|
|
57
|
+
clearCacheEntry: (...args) => {
|
|
58
|
+
const key = getCacheKey(...args);
|
|
59
|
+
cache.delete(key);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
35
64
|
// src/utilities/app-proxy.ts
|
|
65
|
+
var memoizedFetch = memoize(
|
|
66
|
+
(...args) => global.fetch(...args),
|
|
67
|
+
(url) => url
|
|
68
|
+
);
|
|
36
69
|
async function fetchAppProxyConfig({
|
|
37
70
|
appProxyUrl = "/apps/coveo",
|
|
38
71
|
marketId
|
|
39
72
|
}) {
|
|
40
|
-
const
|
|
73
|
+
const url = `${appProxyUrl}?marketId=${marketId}`;
|
|
74
|
+
const response = await memoizedFetch.fn(url);
|
|
75
|
+
if (!response.ok) {
|
|
76
|
+
memoizedFetch.clearCacheEntry(url);
|
|
77
|
+
throw new Error(
|
|
78
|
+
`Failed to fetch app proxy configuration from ${appProxyUrl} for marketId ${marketId}. Status: ${response.status}`
|
|
79
|
+
);
|
|
80
|
+
}
|
|
41
81
|
return response.json();
|
|
42
82
|
}
|
|
83
|
+
function clearAppProxyCache() {
|
|
84
|
+
memoizedFetch.clearCache();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// src/utilities/init.ts
|
|
88
|
+
import { getAnalyticsNextApiBaseUrl } from "@coveo/headless";
|
|
89
|
+
import { createRelay } from "@coveo/relay";
|
|
90
|
+
function init(options) {
|
|
91
|
+
const relay = createRelay({
|
|
92
|
+
url: getAnalyticsNextApiBaseUrl(
|
|
93
|
+
options.organizationId,
|
|
94
|
+
options.environment
|
|
95
|
+
),
|
|
96
|
+
token: options.accessToken,
|
|
97
|
+
trackingId: options.trackingId
|
|
98
|
+
});
|
|
99
|
+
const clientId = relay.getMeta("").clientId;
|
|
100
|
+
publishCustomShopifyEvent(COVEO_SHOPIFY_CONFIG_KEY, {
|
|
101
|
+
...options,
|
|
102
|
+
clientId
|
|
103
|
+
});
|
|
104
|
+
}
|
|
43
105
|
|
|
44
106
|
// src/headless/search.ts
|
|
45
107
|
function buildShopifySearchEngine({
|
|
@@ -50,7 +112,7 @@ function buildShopifySearchEngine({
|
|
|
50
112
|
"The configuration for the search engine must include an analytics tracking ID."
|
|
51
113
|
);
|
|
52
114
|
}
|
|
53
|
-
const
|
|
115
|
+
const options = {
|
|
54
116
|
accessToken: searchEngineOptions.configuration.accessToken,
|
|
55
117
|
organizationId: searchEngineOptions.configuration.organizationId,
|
|
56
118
|
environment: searchEngineOptions.configuration.environment,
|
|
@@ -59,7 +121,7 @@ function buildShopifySearchEngine({
|
|
|
59
121
|
const engine = buildSearchEngine(searchEngineOptions);
|
|
60
122
|
const clientId = engine.relay.getMeta("").clientId;
|
|
61
123
|
publishCustomShopifyEvent(COVEO_SHOPIFY_CONFIG_KEY, {
|
|
62
|
-
...
|
|
124
|
+
...options,
|
|
63
125
|
clientId
|
|
64
126
|
});
|
|
65
127
|
return engine;
|
|
@@ -67,6 +129,8 @@ function buildShopifySearchEngine({
|
|
|
67
129
|
export {
|
|
68
130
|
COVEO_SHOPIFY_CONFIG_KEY,
|
|
69
131
|
buildShopifySearchEngine,
|
|
132
|
+
clearAppProxyCache,
|
|
70
133
|
fetchAppProxyConfig,
|
|
134
|
+
init,
|
|
71
135
|
publishCustomShopifyEvent
|
|
72
136
|
};
|
package/dist/headless/search.js
CHANGED
|
@@ -3,6 +3,7 @@ import { COVEO_SHOPIFY_CONFIG_KEY } from '../constants';
|
|
|
3
3
|
import { publishCustomShopifyEvent } from '../utilities/shopify';
|
|
4
4
|
export { COVEO_SHOPIFY_CONFIG_KEY } from '../constants';
|
|
5
5
|
export * from '@coveo/headless';
|
|
6
|
+
export * from '../constants';
|
|
6
7
|
export * from '../utilities';
|
|
7
8
|
/**
|
|
8
9
|
* Builds the search engine for a Shopify store.
|
|
@@ -19,7 +20,7 @@ export function buildShopifySearchEngine({ searchEngineOptions, }) {
|
|
|
19
20
|
if (!searchEngineOptions.configuration.analytics?.trackingId) {
|
|
20
21
|
throw new Error('The configuration for the search engine must include an analytics tracking ID.');
|
|
21
22
|
}
|
|
22
|
-
const
|
|
23
|
+
const options = {
|
|
23
24
|
accessToken: searchEngineOptions.configuration.accessToken,
|
|
24
25
|
organizationId: searchEngineOptions.configuration.organizationId,
|
|
25
26
|
environment: searchEngineOptions.configuration.environment,
|
|
@@ -28,7 +29,7 @@ export function buildShopifySearchEngine({ searchEngineOptions, }) {
|
|
|
28
29
|
const engine = buildSearchEngine(searchEngineOptions);
|
|
29
30
|
const clientId = engine.relay.getMeta('').clientId;
|
|
30
31
|
publishCustomShopifyEvent(COVEO_SHOPIFY_CONFIG_KEY, {
|
|
31
|
-
...
|
|
32
|
+
...options,
|
|
32
33
|
clientId,
|
|
33
34
|
});
|
|
34
35
|
return engine;
|
package/dist/headless.esm.js
CHANGED
|
@@ -38,7 +38,9 @@ var index_exports = {};
|
|
|
38
38
|
__export(index_exports, {
|
|
39
39
|
COVEO_SHOPIFY_CONFIG_KEY: () => COVEO_SHOPIFY_CONFIG_KEY,
|
|
40
40
|
buildShopifyCommerceEngine: () => buildShopifyCommerceEngine,
|
|
41
|
+
clearAppProxyCache: () => clearAppProxyCache,
|
|
41
42
|
fetchAppProxyConfig: () => fetchAppProxyConfig,
|
|
43
|
+
init: () => init,
|
|
42
44
|
publishCustomShopifyEvent: () => publishCustomShopifyEvent
|
|
43
45
|
});
|
|
44
46
|
|
|
@@ -47,7 +49,9 @@ var commerce_exports = {};
|
|
|
47
49
|
__export(commerce_exports, {
|
|
48
50
|
COVEO_SHOPIFY_CONFIG_KEY: () => COVEO_SHOPIFY_CONFIG_KEY,
|
|
49
51
|
buildShopifyCommerceEngine: () => buildShopifyCommerceEngine,
|
|
52
|
+
clearAppProxyCache: () => clearAppProxyCache,
|
|
50
53
|
fetchAppProxyConfig: () => fetchAppProxyConfig,
|
|
54
|
+
init: () => init,
|
|
51
55
|
publishCustomShopifyEvent: () => publishCustomShopifyEvent
|
|
52
56
|
});
|
|
53
57
|
import {
|
|
@@ -68,20 +72,82 @@ function publishCustomShopifyEvent(key, customData) {
|
|
|
68
72
|
__reExport(commerce_exports, commerce_star);
|
|
69
73
|
import * as commerce_star from "@coveo/headless/commerce";
|
|
70
74
|
|
|
75
|
+
// src/utilities/memoize.ts
|
|
76
|
+
function memoize(fn, getCacheKey) {
|
|
77
|
+
const cache = /* @__PURE__ */ new Map();
|
|
78
|
+
return {
|
|
79
|
+
fn: async (...args) => {
|
|
80
|
+
const key = getCacheKey(...args);
|
|
81
|
+
if (cache.has(key)) {
|
|
82
|
+
return cache.get(key);
|
|
83
|
+
}
|
|
84
|
+
const promise = fn(...args);
|
|
85
|
+
cache.set(key, promise);
|
|
86
|
+
try {
|
|
87
|
+
const result = await promise;
|
|
88
|
+
return result;
|
|
89
|
+
} catch (error) {
|
|
90
|
+
cache.delete(key);
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
clearCache: () => {
|
|
95
|
+
cache.clear();
|
|
96
|
+
},
|
|
97
|
+
clearCacheEntry: (...args) => {
|
|
98
|
+
const key = getCacheKey(...args);
|
|
99
|
+
cache.delete(key);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
71
104
|
// src/utilities/app-proxy.ts
|
|
105
|
+
var memoizedFetch = memoize(
|
|
106
|
+
(...args) => global.fetch(...args),
|
|
107
|
+
(url) => url
|
|
108
|
+
);
|
|
72
109
|
async function fetchAppProxyConfig({
|
|
73
110
|
appProxyUrl = "/apps/coveo",
|
|
74
111
|
marketId
|
|
75
112
|
}) {
|
|
76
|
-
const
|
|
113
|
+
const url = `${appProxyUrl}?marketId=${marketId}`;
|
|
114
|
+
const response = await memoizedFetch.fn(url);
|
|
115
|
+
if (!response.ok) {
|
|
116
|
+
memoizedFetch.clearCacheEntry(url);
|
|
117
|
+
throw new Error(
|
|
118
|
+
`Failed to fetch app proxy configuration from ${appProxyUrl} for marketId ${marketId}. Status: ${response.status}`
|
|
119
|
+
);
|
|
120
|
+
}
|
|
77
121
|
return response.json();
|
|
78
122
|
}
|
|
123
|
+
function clearAppProxyCache() {
|
|
124
|
+
memoizedFetch.clearCache();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// src/utilities/init.ts
|
|
128
|
+
import { getAnalyticsNextApiBaseUrl } from "@coveo/headless";
|
|
129
|
+
import { createRelay } from "@coveo/relay";
|
|
130
|
+
function init(options) {
|
|
131
|
+
const relay = createRelay({
|
|
132
|
+
url: getAnalyticsNextApiBaseUrl(
|
|
133
|
+
options.organizationId,
|
|
134
|
+
options.environment
|
|
135
|
+
),
|
|
136
|
+
token: options.accessToken,
|
|
137
|
+
trackingId: options.trackingId
|
|
138
|
+
});
|
|
139
|
+
const clientId = relay.getMeta("").clientId;
|
|
140
|
+
publishCustomShopifyEvent(COVEO_SHOPIFY_CONFIG_KEY, {
|
|
141
|
+
...options,
|
|
142
|
+
clientId
|
|
143
|
+
});
|
|
144
|
+
}
|
|
79
145
|
|
|
80
146
|
// src/headless/commerce.ts
|
|
81
147
|
function buildShopifyCommerceEngine({
|
|
82
148
|
commerceEngineOptions
|
|
83
149
|
}) {
|
|
84
|
-
const
|
|
150
|
+
const options = {
|
|
85
151
|
accessToken: commerceEngineOptions.configuration.accessToken,
|
|
86
152
|
organizationId: commerceEngineOptions.configuration.organizationId,
|
|
87
153
|
environment: commerceEngineOptions.configuration.environment,
|
|
@@ -90,7 +156,7 @@ function buildShopifyCommerceEngine({
|
|
|
90
156
|
const engine = buildCommerceEngine(commerceEngineOptions);
|
|
91
157
|
const clientId = engine.relay.getMeta("").clientId;
|
|
92
158
|
publishCustomShopifyEvent(COVEO_SHOPIFY_CONFIG_KEY, {
|
|
93
|
-
...
|
|
159
|
+
...options,
|
|
94
160
|
clientId
|
|
95
161
|
});
|
|
96
162
|
return engine;
|
|
@@ -101,6 +167,8 @@ __reExport(index_exports, commerce_exports);
|
|
|
101
167
|
export {
|
|
102
168
|
COVEO_SHOPIFY_CONFIG_KEY,
|
|
103
169
|
buildShopifyCommerceEngine,
|
|
170
|
+
clearAppProxyCache,
|
|
104
171
|
fetchAppProxyConfig,
|
|
172
|
+
init,
|
|
105
173
|
publishCustomShopifyEvent
|
|
106
174
|
};
|
package/dist/types.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { CommerceEngineOptions } from '@coveo/headless/commerce';
|
|
2
|
-
export interface
|
|
2
|
+
export interface AppProxyOptions {
|
|
3
3
|
appProxyUrl?: string;
|
|
4
4
|
marketId: string;
|
|
5
5
|
}
|
|
6
|
-
export interface
|
|
6
|
+
export interface CoveoShopifyOptions {
|
|
7
7
|
accessToken: string;
|
|
8
8
|
organizationId: string;
|
|
9
9
|
environment: CommerceEngineOptions['configuration']['environment'];
|
|
10
10
|
trackingId: string;
|
|
11
11
|
}
|
|
12
|
-
export
|
|
12
|
+
export interface CoveoShopifyCustomEvent extends CoveoShopifyOptions {
|
|
13
13
|
clientId: string;
|
|
14
|
-
}
|
|
14
|
+
}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AppProxyOptions, CoveoShopifyOptions } from '../types';
|
|
2
2
|
/**
|
|
3
3
|
* Fetches configuration from the app proxy.
|
|
4
4
|
*
|
|
5
5
|
* Performs an HTTP GET request to retrieve the app proxy configuration using the provided marketId.
|
|
6
|
-
* The fetched response is parsed as JSON and returned.
|
|
6
|
+
* The fetched response is parsed as JSON and returned. Results are automatically memoized by URL.
|
|
7
7
|
*
|
|
8
8
|
* @param appProxyUrl - The URL template for the app proxy endpoint. Defaults to '/apps/coveo'.
|
|
9
9
|
* @param marketId - The unique market identifier used as a query parameter.
|
|
10
10
|
* @returns A promise that resolves to an object containing the access token, organization ID,
|
|
11
11
|
* environment, and tracking ID.
|
|
12
12
|
*/
|
|
13
|
-
export declare function fetchAppProxyConfig({ appProxyUrl, marketId, }:
|
|
13
|
+
export declare function fetchAppProxyConfig({ appProxyUrl, marketId, }: AppProxyOptions): Promise<CoveoShopifyOptions>;
|
|
14
|
+
export declare function clearAppProxyCache(): void;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { memoize } from './memoize';
|
|
2
|
+
const memoizedFetch = memoize((...args) => global.fetch(...args), (url) => url);
|
|
1
3
|
/**
|
|
2
4
|
* Fetches configuration from the app proxy.
|
|
3
5
|
*
|
|
4
6
|
* Performs an HTTP GET request to retrieve the app proxy configuration using the provided marketId.
|
|
5
|
-
* The fetched response is parsed as JSON and returned.
|
|
7
|
+
* The fetched response is parsed as JSON and returned. Results are automatically memoized by URL.
|
|
6
8
|
*
|
|
7
9
|
* @param appProxyUrl - The URL template for the app proxy endpoint. Defaults to '/apps/coveo'.
|
|
8
10
|
* @param marketId - The unique market identifier used as a query parameter.
|
|
@@ -10,6 +12,14 @@
|
|
|
10
12
|
* environment, and tracking ID.
|
|
11
13
|
*/
|
|
12
14
|
export async function fetchAppProxyConfig({ appProxyUrl = '/apps/coveo', marketId, }) {
|
|
13
|
-
const
|
|
15
|
+
const url = `${appProxyUrl}?marketId=${marketId}`;
|
|
16
|
+
const response = await memoizedFetch.fn(url);
|
|
17
|
+
if (!response.ok) {
|
|
18
|
+
memoizedFetch.clearCacheEntry(url);
|
|
19
|
+
throw new Error(`Failed to fetch app proxy configuration from ${appProxyUrl} for marketId ${marketId}. Status: ${response.status}`);
|
|
20
|
+
}
|
|
14
21
|
return response.json();
|
|
15
22
|
}
|
|
23
|
+
export function clearAppProxyCache() {
|
|
24
|
+
memoizedFetch.clearCache();
|
|
25
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export type
|
|
1
|
+
export type * from '../types';
|
|
2
2
|
export { publishCustomShopifyEvent } from './shopify';
|
|
3
|
-
export
|
|
3
|
+
export * from './app-proxy';
|
|
4
|
+
export * from './init';
|
|
4
5
|
export * from '../constants';
|
package/dist/utilities/index.js
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { getAnalyticsNextApiBaseUrl } from '@coveo/headless';
|
|
2
|
+
import { createRelay } from '@coveo/relay';
|
|
3
|
+
import { COVEO_SHOPIFY_CONFIG_KEY } from '../constants';
|
|
4
|
+
import { publishCustomShopifyEvent } from './shopify';
|
|
5
|
+
export function init(options) {
|
|
6
|
+
const relay = createRelay({
|
|
7
|
+
url: getAnalyticsNextApiBaseUrl(options.organizationId, options.environment),
|
|
8
|
+
token: options.accessToken,
|
|
9
|
+
trackingId: options.trackingId,
|
|
10
|
+
});
|
|
11
|
+
const clientId = relay.getMeta('').clientId;
|
|
12
|
+
publishCustomShopifyEvent(COVEO_SHOPIFY_CONFIG_KEY, {
|
|
13
|
+
...options,
|
|
14
|
+
clientId,
|
|
15
|
+
});
|
|
16
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a memoized version of an async function with a custom cache key generator.
|
|
3
|
+
* Only successful results are cached - rejected promises are not remembered.
|
|
4
|
+
*
|
|
5
|
+
* @param fn - The async function to memoize
|
|
6
|
+
* @param getCacheKey - Function that generates a cache key from the function arguments
|
|
7
|
+
* @returns Object with the memoized function and cache clearing capability
|
|
8
|
+
*/
|
|
9
|
+
export declare function memoize<TArgs extends unknown[], TReturn>(fn: (...args: TArgs) => Promise<TReturn>, getCacheKey: (...args: TArgs) => string): {
|
|
10
|
+
fn: (...args: TArgs) => Promise<TReturn>;
|
|
11
|
+
clearCache: () => void;
|
|
12
|
+
clearCacheEntry: (...args: TArgs) => void;
|
|
13
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a memoized version of an async function with a custom cache key generator.
|
|
3
|
+
* Only successful results are cached - rejected promises are not remembered.
|
|
4
|
+
*
|
|
5
|
+
* @param fn - The async function to memoize
|
|
6
|
+
* @param getCacheKey - Function that generates a cache key from the function arguments
|
|
7
|
+
* @returns Object with the memoized function and cache clearing capability
|
|
8
|
+
*/
|
|
9
|
+
export function memoize(fn, getCacheKey) {
|
|
10
|
+
const cache = new Map();
|
|
11
|
+
return {
|
|
12
|
+
fn: async (...args) => {
|
|
13
|
+
const key = getCacheKey(...args);
|
|
14
|
+
if (cache.has(key)) {
|
|
15
|
+
return cache.get(key);
|
|
16
|
+
}
|
|
17
|
+
const promise = fn(...args);
|
|
18
|
+
cache.set(key, promise);
|
|
19
|
+
try {
|
|
20
|
+
const result = await promise;
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
// Remove failed promises from cache so they can be retried
|
|
25
|
+
cache.delete(key);
|
|
26
|
+
throw error;
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
clearCache: () => {
|
|
30
|
+
cache.clear();
|
|
31
|
+
},
|
|
32
|
+
clearCacheEntry: (...args) => {
|
|
33
|
+
const key = getCacheKey(...args);
|
|
34
|
+
cache.delete(key);
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
}
|
package/dist/utilities.esm.js
CHANGED
|
@@ -23,19 +23,85 @@ function publishCustomShopifyEvent(key, customData) {
|
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
// src/utilities/memoize.ts
|
|
27
|
+
function memoize(fn, getCacheKey) {
|
|
28
|
+
const cache = /* @__PURE__ */ new Map();
|
|
29
|
+
return {
|
|
30
|
+
fn: async (...args) => {
|
|
31
|
+
const key = getCacheKey(...args);
|
|
32
|
+
if (cache.has(key)) {
|
|
33
|
+
return cache.get(key);
|
|
34
|
+
}
|
|
35
|
+
const promise = fn(...args);
|
|
36
|
+
cache.set(key, promise);
|
|
37
|
+
try {
|
|
38
|
+
const result = await promise;
|
|
39
|
+
return result;
|
|
40
|
+
} catch (error) {
|
|
41
|
+
cache.delete(key);
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
clearCache: () => {
|
|
46
|
+
cache.clear();
|
|
47
|
+
},
|
|
48
|
+
clearCacheEntry: (...args) => {
|
|
49
|
+
const key = getCacheKey(...args);
|
|
50
|
+
cache.delete(key);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
26
55
|
// src/utilities/app-proxy.ts
|
|
56
|
+
var memoizedFetch = memoize(
|
|
57
|
+
(...args) => global.fetch(...args),
|
|
58
|
+
(url) => url
|
|
59
|
+
);
|
|
27
60
|
async function fetchAppProxyConfig({
|
|
28
61
|
appProxyUrl = "/apps/coveo",
|
|
29
62
|
marketId
|
|
30
63
|
}) {
|
|
31
|
-
const
|
|
64
|
+
const url = `${appProxyUrl}?marketId=${marketId}`;
|
|
65
|
+
const response = await memoizedFetch.fn(url);
|
|
66
|
+
if (!response.ok) {
|
|
67
|
+
memoizedFetch.clearCacheEntry(url);
|
|
68
|
+
throw new Error(
|
|
69
|
+
`Failed to fetch app proxy configuration from ${appProxyUrl} for marketId ${marketId}. Status: ${response.status}`
|
|
70
|
+
);
|
|
71
|
+
}
|
|
32
72
|
return response.json();
|
|
33
73
|
}
|
|
74
|
+
function clearAppProxyCache() {
|
|
75
|
+
memoizedFetch.clearCache();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// src/utilities/init.ts
|
|
79
|
+
import { getAnalyticsNextApiBaseUrl } from "@coveo/headless";
|
|
80
|
+
import { createRelay } from "@coveo/relay";
|
|
34
81
|
|
|
35
82
|
// src/constants.ts
|
|
36
83
|
var COVEO_SHOPIFY_CONFIG_KEY = "coveo_shopify_config";
|
|
84
|
+
|
|
85
|
+
// src/utilities/init.ts
|
|
86
|
+
function init(options) {
|
|
87
|
+
const relay = createRelay({
|
|
88
|
+
url: getAnalyticsNextApiBaseUrl(
|
|
89
|
+
options.organizationId,
|
|
90
|
+
options.environment
|
|
91
|
+
),
|
|
92
|
+
token: options.accessToken,
|
|
93
|
+
trackingId: options.trackingId
|
|
94
|
+
});
|
|
95
|
+
const clientId = relay.getMeta("").clientId;
|
|
96
|
+
publishCustomShopifyEvent(COVEO_SHOPIFY_CONFIG_KEY, {
|
|
97
|
+
...options,
|
|
98
|
+
clientId
|
|
99
|
+
});
|
|
100
|
+
}
|
|
37
101
|
export {
|
|
38
102
|
COVEO_SHOPIFY_CONFIG_KEY,
|
|
103
|
+
clearAppProxyCache,
|
|
39
104
|
fetchAppProxyConfig,
|
|
105
|
+
init,
|
|
40
106
|
publishCustomShopifyEvent
|
|
41
107
|
};
|
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"main": "./dist/headless.esm.js",
|
|
9
9
|
"module": "./dist/headless.esm.js",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
|
-
"version": "1.
|
|
11
|
+
"version": "1.7.0-pre.153636d7cb",
|
|
12
12
|
"files": [
|
|
13
13
|
"dist/"
|
|
14
14
|
],
|
|
@@ -38,6 +38,11 @@
|
|
|
38
38
|
"types": "./dist/utilities/index.d.ts",
|
|
39
39
|
"import": "./dist/utilities.esm.js",
|
|
40
40
|
"default": "./dist/utilities.esm.js"
|
|
41
|
+
},
|
|
42
|
+
"./constants": {
|
|
43
|
+
"types": "./dist/constants.d.ts",
|
|
44
|
+
"import": "./dist/constants.esm.js",
|
|
45
|
+
"default": "./dist/constants.esm.js"
|
|
41
46
|
}
|
|
42
47
|
},
|
|
43
48
|
"scripts": {
|
|
@@ -56,7 +61,8 @@
|
|
|
56
61
|
"vitest": "3.2.3"
|
|
57
62
|
},
|
|
58
63
|
"dependencies": {
|
|
59
|
-
"@coveo/
|
|
64
|
+
"@coveo/relay": "1.2.1",
|
|
65
|
+
"@coveo/headless": "3.27.0-pre.153636d7cb",
|
|
60
66
|
"uuid": "^11.0.0"
|
|
61
67
|
},
|
|
62
68
|
"engines": {
|