@pack/hydrogen 1.0.1-ab-test.2 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/create-pack-client.d.ts +5 -11
- package/dist/create-pack-client.d.ts.map +1 -1
- package/dist/create-pack-client.js +70 -83
- package/dist/handle-request.d.ts.map +1 -1
- package/dist/handle-request.js +1 -3
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -2
- package/package.json +4 -7
- package/dist/tests/hooks.d.ts +0 -8
- package/dist/tests/hooks.d.ts.map +0 -1
- package/dist/tests/hooks.js +0 -33
- package/dist/tests/index.d.ts +0 -6
- package/dist/tests/index.d.ts.map +0 -1
- package/dist/tests/index.js +0 -5
- package/dist/tests/pack-test-context.d.ts +0 -15
- package/dist/tests/pack-test-context.d.ts.map +0 -1
- package/dist/tests/pack-test-context.js +0 -3
- package/dist/tests/pack-test-provider.d.ts +0 -8
- package/dist/tests/pack-test-provider.d.ts.map +0 -1
- package/dist/tests/pack-test-provider.js +0 -9
- package/dist/tests/pack-test-route.d.ts +0 -2
- package/dist/tests/pack-test-route.d.ts.map +0 -1
- package/dist/tests/pack-test-route.js +0 -29
- package/dist/tests/test.d.ts +0 -45
- package/dist/tests/test.d.ts.map +0 -1
- package/dist/tests/test.js +0 -228
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
import { PackClient } from "@pack/client";
|
|
3
3
|
import { CacheCustom } from "@shopify/hydrogen";
|
|
4
4
|
import { PackSession } from "./session/session";
|
|
5
|
-
import { Test, TestInput } from "./tests/test";
|
|
6
5
|
/** @see https://shopify.dev/docs/custom-storefronts/hydrogen/data-fetching/cache#caching-strategies */
|
|
7
6
|
type CachingStrategy = ReturnType<typeof CacheCustom>;
|
|
8
7
|
interface EnvironmentOptions {
|
|
@@ -17,7 +16,7 @@ interface EnvironmentOptions {
|
|
|
17
16
|
*/
|
|
18
17
|
waitUntil: ExecutionContext["waitUntil"];
|
|
19
18
|
}
|
|
20
|
-
|
|
19
|
+
interface CreatePackClientOptions extends EnvironmentOptions {
|
|
21
20
|
apiUrl?: string;
|
|
22
21
|
token?: string;
|
|
23
22
|
storeId?: string;
|
|
@@ -30,7 +29,6 @@ type Variables = Record<string, any>;
|
|
|
30
29
|
interface QueryOptions {
|
|
31
30
|
variables?: Variables;
|
|
32
31
|
cache?: CachingStrategy;
|
|
33
|
-
test?: TestInput;
|
|
34
32
|
}
|
|
35
33
|
interface QueryError {
|
|
36
34
|
message: string;
|
|
@@ -41,22 +39,18 @@ interface QueryError {
|
|
|
41
39
|
interface QueryResponse<T> {
|
|
42
40
|
data: T | null;
|
|
43
41
|
error: QueryError | null;
|
|
44
|
-
testInfo?: Test;
|
|
45
42
|
}
|
|
46
43
|
export interface Pack {
|
|
47
|
-
|
|
44
|
+
isPreviewModeEnabled: () => boolean;
|
|
45
|
+
session: PackSession;
|
|
46
|
+
query: <T = any>(query: string, options?: QueryOptions) => Promise<QueryResponse<T>>;
|
|
47
|
+
isValidEditToken: PackClient["isValidEditToken"];
|
|
48
48
|
getPackSessionData(): {
|
|
49
49
|
storeId: string;
|
|
50
50
|
sessionId: string;
|
|
51
|
-
abTest: Test | null | undefined;
|
|
52
51
|
isPreviewModeEnabled: boolean;
|
|
53
52
|
customizerMeta: any;
|
|
54
53
|
};
|
|
55
|
-
handleRequest(request: Request): Promise<(response: Response) => void>;
|
|
56
|
-
isPreviewModeEnabled: () => boolean;
|
|
57
|
-
isValidEditToken: PackClient["isValidEditToken"];
|
|
58
|
-
query: <T = any>(query: string, options?: QueryOptions) => Promise<QueryResponse<T>>;
|
|
59
|
-
session: PackSession;
|
|
60
54
|
}
|
|
61
55
|
interface DefaultThemeData {
|
|
62
56
|
data: Record<string, any>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-pack-client.d.ts","sourceRoot":"","sources":["../src/create-pack-client.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAmB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"create-pack-client.d.ts","sourceRoot":"","sources":["../src/create-pack-client.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAmB,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,uGAAuG;AACvG,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAEtD,UAAU,kBAAkB;IAC1B;;;OAGG;IACH,KAAK,EAAE,KAAK,CAAC;IACb;;;OAGG;IACH,SAAS,EAAE,gBAAgB,CAAC,WAAW,CAAC,CAAC;CAC1C;AAED,UAAU,uBAAwB,SAAQ,kBAAkB;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,WAAW,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,0DAA0D;IAC1D,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC;AAED,KAAK,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAErC,UAAU,YAAY;IACpB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,KAAK,CAAC,EAAE,eAAe,CAAC;CACzB;AAED,UAAU,UAAU;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,aAAa,CAAC,CAAC;IACvB,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IACf,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,IAAI;IACnB,oBAAoB,EAAE,MAAM,OAAO,CAAC;IACpC,OAAO,EAAE,WAAW,CAAC;IACrB,KAAK,EAAE,CAAC,CAAC,GAAG,GAAG,EACb,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,YAAY,KACnB,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,gBAAgB,EAAE,UAAU,CAAC,kBAAkB,CAAC,CAAC;IAEjD,kBAAkB,IAAI;QACpB,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,oBAAoB,EAAE,OAAO,CAAC;QAC9B,cAAc,EAAE,GAAG,CAAC;KACrB,CAAC;CACH;AAED,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC3B;AAoJD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,IAAI,CAsIvE"}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { PackClient } from "@pack/client";
|
|
2
2
|
import { CacheCustom, createWithCache } from "@shopify/hydrogen";
|
|
3
|
-
import cookie from "cookie";
|
|
4
|
-
import { getTestInfo, getTestFromQueryParams, getTestSession, getTestTargetingAttributesFromRequest, setTestHeaders, } from "./tests/test";
|
|
5
3
|
/**
|
|
6
4
|
* Create an SHA-256 hash as a hex string
|
|
7
5
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest#converting_a_digest_to_a_hex_string
|
|
@@ -28,6 +26,43 @@ function hashQuery(query, variables, headers) {
|
|
|
28
26
|
hash += JSON.stringify(headers);
|
|
29
27
|
return sha256(hash);
|
|
30
28
|
}
|
|
29
|
+
async function getCacheKey(withCache, query, token, options) {
|
|
30
|
+
let queryHash = await hashQuery(query, options?.variables, options?.headers);
|
|
31
|
+
let publishedAt;
|
|
32
|
+
try {
|
|
33
|
+
const resp = await withCache("pack:content:publishedAt", CacheCustom({
|
|
34
|
+
maxAge: 15,
|
|
35
|
+
staleWhileRevalidate: 15,
|
|
36
|
+
}), async () => {
|
|
37
|
+
const URL = "https://cache-check-production.packdigital.workers.dev/published-at";
|
|
38
|
+
const resp = await fetch(URL, {
|
|
39
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
40
|
+
});
|
|
41
|
+
const { status } = resp;
|
|
42
|
+
if (status !== 200) {
|
|
43
|
+
let message;
|
|
44
|
+
if (status === 401) {
|
|
45
|
+
message =
|
|
46
|
+
"Pack error: Unauthorized request to cache check service. Please check your token.";
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
message = `Pack error: Request to cache check service failed with status ${status}`;
|
|
50
|
+
}
|
|
51
|
+
console.error(message);
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
return resp.json();
|
|
55
|
+
});
|
|
56
|
+
publishedAt = resp?.publishedAt;
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
console.error(err);
|
|
60
|
+
}
|
|
61
|
+
if (publishedAt) {
|
|
62
|
+
return `${queryHash}:${publishedAt}`;
|
|
63
|
+
}
|
|
64
|
+
return queryHash;
|
|
65
|
+
}
|
|
31
66
|
// Extends the CacheLong strategy with a stale-if-error policy
|
|
32
67
|
const cacheCustom = CacheCustom({
|
|
33
68
|
maxAge: 3600,
|
|
@@ -78,61 +113,16 @@ export function createPackClient(options) {
|
|
|
78
113
|
const previewEnabled = !!session.get("previewEnabled");
|
|
79
114
|
const previewEnvironment = session.get("environment");
|
|
80
115
|
const clientContentEnvironment = previewEnvironment || contentEnvironment;
|
|
81
|
-
let packClient;
|
|
82
|
-
let testFromQueryParams = null;
|
|
83
|
-
let testInfoForRequest = undefined;
|
|
84
116
|
if (!token && !defaultThemeData) {
|
|
85
117
|
throw new Error("The Pack client token is missing or empty. Please provide a valid token or default theme data.");
|
|
86
118
|
}
|
|
87
119
|
if (!storeId) {
|
|
88
120
|
throw new Error("The Pack Store ID is missing or empty. Please provide a valid Store ID.");
|
|
89
121
|
}
|
|
90
|
-
const handleRequest = async (request) => {
|
|
91
|
-
testFromQueryParams = getTestFromQueryParams(request);
|
|
92
|
-
const testTargetAudienceAttributes = getTestTargetingAttributesFromRequest(request);
|
|
93
|
-
if (packClient) {
|
|
94
|
-
testInfoForRequest = await getTestInfo({
|
|
95
|
-
request,
|
|
96
|
-
testTargetAudienceAttributes,
|
|
97
|
-
packClient,
|
|
98
|
-
session,
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
return (response) => {
|
|
102
|
-
const hasExposedTestCookie = request.headers
|
|
103
|
-
.get("cookie")
|
|
104
|
-
?.includes("exposedTest");
|
|
105
|
-
if (hasExposedTestCookie) {
|
|
106
|
-
// Clear the exposedTest cookie
|
|
107
|
-
response.headers.set("Set-Cookie", cookie.serialize("exposedTest", "", {
|
|
108
|
-
maxAge: 0,
|
|
109
|
-
}));
|
|
110
|
-
}
|
|
111
|
-
};
|
|
112
|
-
};
|
|
113
|
-
const getTestInfoForLoader = () => {
|
|
114
|
-
let testInfoForLoader = undefined;
|
|
115
|
-
if (testInfoForRequest?.isFirstExposure) {
|
|
116
|
-
const { isFirstExposure, ...testInfo } = testInfoForRequest;
|
|
117
|
-
testInfoForLoader = testInfo;
|
|
118
|
-
}
|
|
119
|
-
return testInfoForLoader;
|
|
120
|
-
};
|
|
121
122
|
if (!token) {
|
|
122
123
|
return {
|
|
123
|
-
|
|
124
|
-
handleRequest,
|
|
125
|
-
getPackSessionData: () => {
|
|
126
|
-
return {
|
|
127
|
-
storeId: storeId,
|
|
128
|
-
sessionId: session.id,
|
|
129
|
-
abTest: getTestSession(session, testFromQueryParams, previewEnabled),
|
|
130
|
-
isPreviewModeEnabled: previewEnabled,
|
|
131
|
-
customizerMeta: session.get("customizerMeta"),
|
|
132
|
-
};
|
|
133
|
-
},
|
|
124
|
+
session,
|
|
134
125
|
isPreviewModeEnabled: () => previewEnabled,
|
|
135
|
-
isValidEditToken: () => new Promise(() => false),
|
|
136
126
|
async query(query, { variables } = {}) {
|
|
137
127
|
if (!defaultThemeData?.data) {
|
|
138
128
|
console.warn("Invalid default theme data provided to Pack client.");
|
|
@@ -141,10 +131,18 @@ export function createPackClient(options) {
|
|
|
141
131
|
const data = resolveQuery({ query, variables, defaultThemeData });
|
|
142
132
|
return { data: data, error: null };
|
|
143
133
|
},
|
|
144
|
-
|
|
134
|
+
isValidEditToken: () => new Promise(() => false),
|
|
135
|
+
getPackSessionData: () => {
|
|
136
|
+
return {
|
|
137
|
+
storeId: storeId,
|
|
138
|
+
sessionId: session.id,
|
|
139
|
+
isPreviewModeEnabled: previewEnabled,
|
|
140
|
+
customizerMeta: session.get("customizerMeta"),
|
|
141
|
+
};
|
|
142
|
+
},
|
|
145
143
|
};
|
|
146
144
|
}
|
|
147
|
-
packClient = new PackClient({
|
|
145
|
+
const packClient = new PackClient({
|
|
148
146
|
// Use apiUrl, it is configured
|
|
149
147
|
// Use active API URL if preview mode is enabled
|
|
150
148
|
// Otherwise, Live PackClient uses its internal configuration
|
|
@@ -157,33 +155,17 @@ export function createPackClient(options) {
|
|
|
157
155
|
token,
|
|
158
156
|
contentEnvironment: clientContentEnvironment,
|
|
159
157
|
sessionId: session.id,
|
|
158
|
+
clientName: "HydrogenClient",
|
|
160
159
|
});
|
|
161
160
|
return {
|
|
162
|
-
|
|
163
|
-
getPackSessionData: () => {
|
|
164
|
-
return {
|
|
165
|
-
storeId: storeId,
|
|
166
|
-
sessionId: session.id,
|
|
167
|
-
abTest: getTestSession(session, testFromQueryParams, previewEnabled),
|
|
168
|
-
isPreviewModeEnabled: previewEnabled,
|
|
169
|
-
customizerMeta: session.get("customizerMeta"),
|
|
170
|
-
};
|
|
171
|
-
},
|
|
172
|
-
handleRequest,
|
|
161
|
+
session,
|
|
173
162
|
isPreviewModeEnabled: () => previewEnabled,
|
|
174
|
-
|
|
175
|
-
async query(query, { variables, cache: strategy = cacheCustom, test } = {}) {
|
|
176
|
-
let headers = {};
|
|
163
|
+
async query(query, { variables, cache: strategy = cacheCustom } = {}) {
|
|
177
164
|
const withCache = createWithCache({
|
|
178
165
|
cache,
|
|
179
166
|
waitUntil,
|
|
180
167
|
});
|
|
181
|
-
headers =
|
|
182
|
-
previewEnabled,
|
|
183
|
-
testInfoForRequest,
|
|
184
|
-
testFromQueryParams: testFromQueryParams || test,
|
|
185
|
-
});
|
|
186
|
-
const queryHash = await hashQuery(query, variables, headers);
|
|
168
|
+
let headers = {};
|
|
187
169
|
const queryVariables = variables ? { ...variables } : {};
|
|
188
170
|
if (previewEnabled) {
|
|
189
171
|
queryVariables.version = "CURRENT";
|
|
@@ -191,23 +173,23 @@ export function createPackClient(options) {
|
|
|
191
173
|
else {
|
|
192
174
|
queryVariables.version = "PUBLISHED";
|
|
193
175
|
}
|
|
194
|
-
const testInfoForLoader = getTestInfoForLoader();
|
|
195
176
|
// Preview mode always bypasses the cache
|
|
196
177
|
if (previewEnabled) {
|
|
197
178
|
try {
|
|
198
|
-
return {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
})),
|
|
203
|
-
testInfo: testInfoForLoader,
|
|
204
|
-
};
|
|
179
|
+
return await packClient.fetch(query, {
|
|
180
|
+
variables: queryVariables,
|
|
181
|
+
headers: headers,
|
|
182
|
+
});
|
|
205
183
|
}
|
|
206
184
|
catch (error) {
|
|
207
185
|
return { error, data: {} };
|
|
208
186
|
}
|
|
209
187
|
}
|
|
210
|
-
const
|
|
188
|
+
const queryHash = await getCacheKey(withCache, query, token, {
|
|
189
|
+
variables: queryVariables,
|
|
190
|
+
headers,
|
|
191
|
+
});
|
|
192
|
+
return withCache(queryHash, strategy, async () => {
|
|
211
193
|
try {
|
|
212
194
|
return await packClient.fetch(query, {
|
|
213
195
|
variables: queryVariables,
|
|
@@ -218,10 +200,15 @@ export function createPackClient(options) {
|
|
|
218
200
|
return { error, data: {} };
|
|
219
201
|
}
|
|
220
202
|
});
|
|
221
|
-
return response.error
|
|
222
|
-
? response
|
|
223
|
-
: { ...response, testInfo: testInfoForLoader };
|
|
224
203
|
},
|
|
225
|
-
|
|
204
|
+
isValidEditToken: (token) => packClient.isValidEditToken(token),
|
|
205
|
+
getPackSessionData: () => {
|
|
206
|
+
return {
|
|
207
|
+
storeId: storeId,
|
|
208
|
+
sessionId: session.id,
|
|
209
|
+
isPreviewModeEnabled: previewEnabled,
|
|
210
|
+
customizerMeta: session.get("customizerMeta"),
|
|
211
|
+
};
|
|
212
|
+
},
|
|
226
213
|
};
|
|
227
214
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handle-request.d.ts","sourceRoot":"","sources":["../src/handle-request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAG5C,wBAAsB,aAAa,CACjC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,GACrD,OAAO,CAAC,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"handle-request.d.ts","sourceRoot":"","sources":["../src/handle-request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAG5C,wBAAsB,aAAa,CACjC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,GACrD,OAAO,CAAC,QAAQ,CAAC,CAanB"}
|
package/dist/handle-request.js
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import { packlytics } from "@pack/packlytics";
|
|
2
2
|
export async function handleRequest(pack, request, handleRequest) {
|
|
3
|
-
const
|
|
4
|
-
const [response] = await Promise.all([
|
|
3
|
+
const [response, _] = await Promise.all([
|
|
5
4
|
handleRequest(request),
|
|
6
5
|
packlytics(request, pack.session, {
|
|
7
6
|
storeFrontId: pack.getPackSessionData().storeId,
|
|
8
7
|
sessionSecret: pack.session.secret,
|
|
9
8
|
}),
|
|
10
9
|
]);
|
|
11
|
-
packHandleResponse(response);
|
|
12
10
|
response.headers.append("powered-by", "Shopify, Hydrogen + Pack Digital");
|
|
13
11
|
response.headers.append("Set-Cookie", await pack.session.commit());
|
|
14
12
|
return response;
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,5 @@ import { usePackCookies } from "./session/usePackCookies";
|
|
|
3
3
|
import { PackSession } from "./session/session";
|
|
4
4
|
import { createPackClient } from "./create-pack-client";
|
|
5
5
|
import { action as previewModeAction, loader as previewModeLoader } from "./preview/preview-mode";
|
|
6
|
-
|
|
7
|
-
export { PackSession, createPackClient, handleRequest, previewModeAction, previewModeLoader, usePackCookies, PackTestContext, usePackTestContext, PackTestProvider, PackTestRoute, useAbTest, useAbTestId, useAbTestHandle, useAbTestSessionId, useAbTestVariantId, useAbTestVariantHandle, };
|
|
6
|
+
export { PackSession, createPackClient, handleRequest, previewModeAction, previewModeLoader, usePackCookies, };
|
|
8
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EACL,MAAM,IAAI,iBAAiB,EAC3B,MAAM,IAAI,iBAAiB,EAC5B,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EACL,MAAM,IAAI,iBAAiB,EAC3B,MAAM,IAAI,iBAAiB,EAC5B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,GACf,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -3,5 +3,4 @@ import { usePackCookies } from "./session/usePackCookies";
|
|
|
3
3
|
import { PackSession } from "./session/session";
|
|
4
4
|
import { createPackClient } from "./create-pack-client";
|
|
5
5
|
import { action as previewModeAction, loader as previewModeLoader, } from "./preview/preview-mode";
|
|
6
|
-
|
|
7
|
-
export { PackSession, createPackClient, handleRequest, previewModeAction, previewModeLoader, usePackCookies, PackTestContext, usePackTestContext, PackTestProvider, PackTestRoute, useAbTest, useAbTestId, useAbTestHandle, useAbTestSessionId, useAbTestVariantId, useAbTestVariantHandle, };
|
|
6
|
+
export { PackSession, createPackClient, handleRequest, previewModeAction, previewModeLoader, usePackCookies, };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pack/hydrogen",
|
|
3
3
|
"description": "Pack Hydrogen",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.2",
|
|
5
5
|
"exports": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
7
7
|
"engines": {
|
|
@@ -22,17 +22,14 @@
|
|
|
22
22
|
"dist"
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@pack/client": "^1.0.1
|
|
26
|
-
"@pack/packlytics": "^1.0.
|
|
27
|
-
"@shopify/hydrogen": "^2023.10.2"
|
|
28
|
-
"cookie": "^0.6.0",
|
|
29
|
-
"js-cookie": "^3.0.5"
|
|
25
|
+
"@pack/client": "^1.0.1",
|
|
26
|
+
"@pack/packlytics": "^1.0.0",
|
|
27
|
+
"@shopify/hydrogen": "^2023.10.2"
|
|
30
28
|
},
|
|
31
29
|
"devDependencies": {
|
|
32
30
|
"@remix-run/server-runtime": "^2.0.0",
|
|
33
31
|
"@shopify/oxygen-workers-types": "^4.0.0",
|
|
34
32
|
"@shopify/remix-oxygen": "^2.0.1",
|
|
35
|
-
"@types/js-cookie": "^3.0.6",
|
|
36
33
|
"@types/node": "^20.11.17"
|
|
37
34
|
},
|
|
38
35
|
"peerDependencies": {
|
package/dist/tests/hooks.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { Test } from "./test";
|
|
2
|
-
export declare function useAbTest(): Test | null;
|
|
3
|
-
export declare function useAbTestSessionId(): string;
|
|
4
|
-
export declare function useAbTestId(): string | undefined;
|
|
5
|
-
export declare function useAbTestHandle(): string | undefined;
|
|
6
|
-
export declare function useAbTestVariantId(): string | undefined;
|
|
7
|
-
export declare function useAbTestVariantHandle(): string | undefined;
|
|
8
|
-
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/tests/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAG9B,wBAAgB,SAAS,IAAI,IAAI,GAAG,IAAI,CAWvC;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAW3C;AAED,wBAAgB,WAAW,IAAI,MAAM,GAAG,SAAS,CAIhD;AAED,wBAAgB,eAAe,IAAI,MAAM,GAAG,SAAS,CAIpD;AAED,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,SAAS,CAIvD;AAED,wBAAgB,sBAAsB,IAAI,MAAM,GAAG,SAAS,CAI3D"}
|
package/dist/tests/hooks.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { useRouteLoaderData } from "@remix-run/react";
|
|
2
|
-
export function useAbTest() {
|
|
3
|
-
// @ts-ignore
|
|
4
|
-
const { abTest: test } = useRouteLoaderData("root");
|
|
5
|
-
if (test === undefined) {
|
|
6
|
-
throw new Error("No A/B test found, are you sure you have call ...pack.getPackSessionData() on root loader return?");
|
|
7
|
-
}
|
|
8
|
-
return test;
|
|
9
|
-
}
|
|
10
|
-
export function useAbTestSessionId() {
|
|
11
|
-
// @ts-ignore
|
|
12
|
-
const { sessionId } = useRouteLoaderData("root");
|
|
13
|
-
if (!sessionId) {
|
|
14
|
-
throw new Error("No Session ID found, are you sure you have call ...pack.getPackSessionData() on root loader return?");
|
|
15
|
-
}
|
|
16
|
-
return sessionId;
|
|
17
|
-
}
|
|
18
|
-
export function useAbTestId() {
|
|
19
|
-
const test = useAbTest();
|
|
20
|
-
return test?.id;
|
|
21
|
-
}
|
|
22
|
-
export function useAbTestHandle() {
|
|
23
|
-
const test = useAbTest();
|
|
24
|
-
return test?.handle;
|
|
25
|
-
}
|
|
26
|
-
export function useAbTestVariantId() {
|
|
27
|
-
const test = useAbTest();
|
|
28
|
-
return test?.testVariant?.id;
|
|
29
|
-
}
|
|
30
|
-
export function useAbTestVariantHandle() {
|
|
31
|
-
const test = useAbTest();
|
|
32
|
-
return test?.testVariant?.handle;
|
|
33
|
-
}
|
package/dist/tests/index.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { PackTestRoute } from "./pack-test-route";
|
|
2
|
-
import { PackTestContext, usePackTestContext } from "./pack-test-context";
|
|
3
|
-
import { PackTestProvider } from "./pack-test-provider";
|
|
4
|
-
import { useAbTest, useAbTestHandle, useAbTestId, useAbTestSessionId, useAbTestVariantHandle, useAbTestVariantId } from "./hooks";
|
|
5
|
-
export { PackTestContext, usePackTestContext, PackTestProvider, PackTestRoute, useAbTest, useAbTestId, useAbTestHandle, useAbTestSessionId, useAbTestVariantId, useAbTestVariantHandle, };
|
|
6
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tests/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EACL,SAAS,EACT,eAAe,EACf,WAAW,EACX,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,EACnB,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,EACb,SAAS,EACT,WAAW,EACX,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,sBAAsB,GACvB,CAAC"}
|
package/dist/tests/index.js
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { PackTestRoute } from "./pack-test-route";
|
|
2
|
-
import { PackTestContext, usePackTestContext } from "./pack-test-context";
|
|
3
|
-
import { PackTestProvider } from "./pack-test-provider";
|
|
4
|
-
import { useAbTest, useAbTestHandle, useAbTestId, useAbTestSessionId, useAbTestVariantHandle, useAbTestVariantId, } from "./hooks";
|
|
5
|
-
export { PackTestContext, usePackTestContext, PackTestProvider, PackTestRoute, useAbTest, useAbTestId, useAbTestHandle, useAbTestSessionId, useAbTestVariantId, useAbTestVariantHandle, };
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export interface Test {
|
|
2
|
-
id: string;
|
|
3
|
-
handle: string;
|
|
4
|
-
testVariant: {
|
|
5
|
-
id: string;
|
|
6
|
-
handle: string;
|
|
7
|
-
};
|
|
8
|
-
}
|
|
9
|
-
type PackTestContextValue = {
|
|
10
|
-
testExposureCallback?: (test: Test) => void;
|
|
11
|
-
};
|
|
12
|
-
export declare const PackTestContext: import("react").Context<PackTestContextValue>;
|
|
13
|
-
export declare const usePackTestContext: () => PackTestContextValue;
|
|
14
|
-
export {};
|
|
15
|
-
//# sourceMappingURL=pack-test-context.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pack-test-context.d.ts","sourceRoot":"","sources":["../../src/tests/pack-test-context.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE;QACX,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED,KAAK,oBAAoB,GAAG;IAC1B,oBAAoB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;CAC7C,CAAC;AAEF,eAAO,MAAM,eAAe,+CAA0C,CAAC;AAEvE,eAAO,MAAM,kBAAkB,4BAAoC,CAAC"}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import React, { PropsWithChildren } from "react";
|
|
2
|
-
import { Test } from "./pack-test-context";
|
|
3
|
-
interface PackContentProps {
|
|
4
|
-
testExposureCallback?: (test: Test) => void;
|
|
5
|
-
}
|
|
6
|
-
export declare function PackTestProvider({ children, testExposureCallback, }: PropsWithChildren<PackContentProps>): React.JSX.Element;
|
|
7
|
-
export {};
|
|
8
|
-
//# sourceMappingURL=pack-test-provider.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pack-test-provider.d.ts","sourceRoot":"","sources":["../../src/tests/pack-test-provider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AACjD,OAAO,EAAmB,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAE5D,UAAU,gBAAgB;IACxB,oBAAoB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;CAC7C;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,QAAQ,EACR,oBAAoB,GACrB,EAAE,iBAAiB,CAAC,gBAAgB,CAAC,qBAYrC"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { PackTestContext } from "./pack-test-context";
|
|
3
|
-
export function PackTestProvider({ children, testExposureCallback, }) {
|
|
4
|
-
return (React.createElement(PackTestContext.Provider, { value: {
|
|
5
|
-
testExposureCallback: (test) => {
|
|
6
|
-
testExposureCallback && testExposureCallback(test);
|
|
7
|
-
},
|
|
8
|
-
} }, children));
|
|
9
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pack-test-route.d.ts","sourceRoot":"","sources":["../../src/tests/pack-test-route.ts"],"names":[],"mappings":"AAuCA,eAAO,MAAM,aAAa,YAIzB,CAAC"}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { useLoaderData } from "@remix-run/react";
|
|
2
|
-
import Cookies from "js-cookie";
|
|
3
|
-
import { useEffect } from "react";
|
|
4
|
-
import { useRevalidator } from "react-router-dom";
|
|
5
|
-
import { usePackTestContext } from "./pack-test-context";
|
|
6
|
-
const usePackLoaderData = () => {
|
|
7
|
-
const { testInfo } = useLoaderData();
|
|
8
|
-
const { testExposureCallback } = usePackTestContext();
|
|
9
|
-
const revalidator = useRevalidator();
|
|
10
|
-
const exposedTestCookieString = Cookies.get("exposedTest");
|
|
11
|
-
useEffect(() => {
|
|
12
|
-
if (testInfo && !exposedTestCookieString) {
|
|
13
|
-
// Set exposedTest cookie used by server to determine if session has been exposed to test
|
|
14
|
-
const expires = new Date();
|
|
15
|
-
expires.setHours(expires.getHours() + 24);
|
|
16
|
-
Cookies.set("exposedTest", JSON.stringify(testInfo), {
|
|
17
|
-
expires,
|
|
18
|
-
});
|
|
19
|
-
testExposureCallback?.(testInfo);
|
|
20
|
-
// TODO: This results in flashing of UI driven by site settings data.
|
|
21
|
-
// Need non-flashing solution.
|
|
22
|
-
revalidator.revalidate();
|
|
23
|
-
}
|
|
24
|
-
}, [testInfo, testExposureCallback]);
|
|
25
|
-
};
|
|
26
|
-
export const PackTestRoute = () => {
|
|
27
|
-
usePackLoaderData();
|
|
28
|
-
return null;
|
|
29
|
-
};
|
package/dist/tests/test.d.ts
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { PackClient } from "@pack/client";
|
|
2
|
-
import { PackSession } from "../session/session";
|
|
3
|
-
export interface TestInput {
|
|
4
|
-
testId?: string;
|
|
5
|
-
testHandle?: string;
|
|
6
|
-
testVariantId?: string;
|
|
7
|
-
testVariantHandle?: string;
|
|
8
|
-
}
|
|
9
|
-
export interface Test {
|
|
10
|
-
id: string;
|
|
11
|
-
handle: string;
|
|
12
|
-
testVariant: {
|
|
13
|
-
id: string;
|
|
14
|
-
handle: string;
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
export interface TestTargetAudienceAttributes {
|
|
18
|
-
url?: string;
|
|
19
|
-
query?: string;
|
|
20
|
-
path?: string;
|
|
21
|
-
utmCampaign?: string;
|
|
22
|
-
utmContent?: string;
|
|
23
|
-
utmMedium?: string;
|
|
24
|
-
utmSource?: string;
|
|
25
|
-
utmTerm?: string;
|
|
26
|
-
}
|
|
27
|
-
export interface GetTestInfoOptions {
|
|
28
|
-
request: Request;
|
|
29
|
-
testTargetAudienceAttributes: TestTargetAudienceAttributes | null;
|
|
30
|
-
packClient: PackClient;
|
|
31
|
-
session: PackSession | undefined;
|
|
32
|
-
}
|
|
33
|
-
export interface TestInfo extends Test {
|
|
34
|
-
isFirstExposure?: boolean;
|
|
35
|
-
}
|
|
36
|
-
export declare function getTestInfo({ request, testTargetAudienceAttributes, packClient, session, }: GetTestInfoOptions): Promise<TestInfo | undefined>;
|
|
37
|
-
export declare function getTestSession(session: PackSession | undefined, testFromQueryParams: TestInput | null, previewEnabled: boolean): Test | null | undefined;
|
|
38
|
-
export declare function getTestTargetingAttributesFromRequest(request: Request): TestTargetAudienceAttributes;
|
|
39
|
-
export declare function getTestFromQueryParams(request: Request): TestInput | null;
|
|
40
|
-
export declare function setTestHeaders(headers: any, options: {
|
|
41
|
-
previewEnabled: boolean;
|
|
42
|
-
testInfoForRequest?: TestInfo;
|
|
43
|
-
testFromQueryParams?: TestInput;
|
|
44
|
-
}): any;
|
|
45
|
-
//# sourceMappingURL=test.d.ts.map
|
package/dist/tests/test.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../src/tests/test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGjD,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE;QACX,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED,MAAM,WAAW,4BAA4B;IAC3C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAqBD,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,4BAA4B,EAAE,4BAA4B,GAAG,IAAI,CAAC;IAClE,UAAU,EAAE,UAAU,CAAC;IACvB,OAAO,EAAE,WAAW,GAAG,SAAS,CAAC;CAClC;AAED,MAAM,WAAW,QAAS,SAAQ,IAAI;IACpC,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,wBAAsB,WAAW,CAAC,EAChC,OAAO,EACP,4BAA4B,EAC5B,UAAU,EACV,OAAO,GACR,EAAE,kBAAkB,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAmHpD;AAED,wBAAgB,cAAc,CAC5B,OAAO,EAAE,WAAW,GAAG,SAAS,EAChC,mBAAmB,EAAE,SAAS,GAAG,IAAI,EACrC,cAAc,EAAE,OAAO,GACtB,IAAI,GAAG,IAAI,GAAG,SAAS,CA8BzB;AAED,wBAAgB,qCAAqC,CACnD,OAAO,EAAE,OAAO,GACf,4BAA4B,CA0B9B;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI,CA2CzE;AAED,wBAAgB,cAAc,CAC5B,OAAO,EAAE,GAAG,EACZ,OAAO,EAAE;IACP,cAAc,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,QAAQ,CAAC;IAC9B,mBAAmB,CAAC,EAAE,SAAS,CAAC;CACjC,OAmCF"}
|
package/dist/tests/test.js
DELETED
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
import cookie from "cookie";
|
|
2
|
-
const QUERY_TEST_BY_RULES = `#graphql
|
|
3
|
-
query TestByRules($testTargetAudienceAttributes: JSON!) {
|
|
4
|
-
testByRules(attributes: $testTargetAudienceAttributes) {
|
|
5
|
-
id
|
|
6
|
-
handle
|
|
7
|
-
testVariant {
|
|
8
|
-
id
|
|
9
|
-
handle
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
`;
|
|
14
|
-
const QUERY_TEST_VARIANT_IS_RUNNING = `#graphql
|
|
15
|
-
query TestVariantIsRunning($handle: String!, $testId: ID!) {
|
|
16
|
-
testVariantIsRunning(handle: $handle, testId: $testId)
|
|
17
|
-
}
|
|
18
|
-
`;
|
|
19
|
-
export async function getTestInfo({ request, testTargetAudienceAttributes, packClient, session, }) {
|
|
20
|
-
let testInfo = undefined;
|
|
21
|
-
if (session) {
|
|
22
|
-
// Request directly to API if it is using CDN to reduce latency
|
|
23
|
-
let isUsingCdn = false;
|
|
24
|
-
if (packClient.apiUrl === "https://apicdn.packdigital.com/graphql") {
|
|
25
|
-
packClient.apiUrl = "https://app.packdigital.com/graphql";
|
|
26
|
-
isUsingCdn = true;
|
|
27
|
-
}
|
|
28
|
-
const packClientFetchTestByRules = packClient.fetch(QUERY_TEST_BY_RULES, {
|
|
29
|
-
variables: {
|
|
30
|
-
testTargetAudienceAttributes,
|
|
31
|
-
},
|
|
32
|
-
});
|
|
33
|
-
const fetchTestByRulesSetTestinfoAsFirstExposure = async () => {
|
|
34
|
-
const resp = await packClientFetchTestByRules;
|
|
35
|
-
const responseTest = resp.data?.testByRules;
|
|
36
|
-
if (responseTest) {
|
|
37
|
-
testInfo = {
|
|
38
|
-
...responseTest,
|
|
39
|
-
isFirstExposure: true,
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
session.set("test", undefined);
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
const testSession = session.get("test");
|
|
47
|
-
let exposedTest = undefined;
|
|
48
|
-
const exposedTestCookieString = cookie.parse(request.headers.get("cookie") || "")?.exposedTest;
|
|
49
|
-
if (exposedTestCookieString) {
|
|
50
|
-
exposedTest = JSON.parse(exposedTestCookieString);
|
|
51
|
-
}
|
|
52
|
-
// If there is no assigned test on the session and an exposed test in the
|
|
53
|
-
// incoming request cookie it means that the user was exposed to a test
|
|
54
|
-
// for the first time previously.
|
|
55
|
-
if (!testSession && exposedTest) {
|
|
56
|
-
// Verify test is still running
|
|
57
|
-
const resp = await packClient.fetch(QUERY_TEST_VARIANT_IS_RUNNING, {
|
|
58
|
-
variables: {
|
|
59
|
-
handle: exposedTest.testVariant.handle,
|
|
60
|
-
testId: exposedTest.id,
|
|
61
|
-
},
|
|
62
|
-
});
|
|
63
|
-
// If the test is still running, set testInfo to the exposed test
|
|
64
|
-
if (!!resp.data.testVariantIsRunning) {
|
|
65
|
-
const { id, handle, testVariant } = exposedTest;
|
|
66
|
-
testInfo = {
|
|
67
|
-
id,
|
|
68
|
-
handle,
|
|
69
|
-
testVariant,
|
|
70
|
-
};
|
|
71
|
-
session.set("test", {
|
|
72
|
-
data: testInfo,
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
else {
|
|
76
|
-
// If the test is not running anymore, fetch a new test for the user
|
|
77
|
-
await fetchTestByRulesSetTestinfoAsFirstExposure();
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
if (!testSession) {
|
|
82
|
-
// If there is no assigned test on the session, check if there is a test
|
|
83
|
-
// for attributes, then assign to session and return value.
|
|
84
|
-
await fetchTestByRulesSetTestinfoAsFirstExposure();
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
// If there is test on session, check if the test on session is still running.
|
|
88
|
-
const packClientFetchTestVariantIsRunning = packClient.fetch(QUERY_TEST_VARIANT_IS_RUNNING, {
|
|
89
|
-
variables: {
|
|
90
|
-
handle: testSession.data.testVariant.handle,
|
|
91
|
-
testId: testSession.data.id,
|
|
92
|
-
},
|
|
93
|
-
});
|
|
94
|
-
const resp = await packClientFetchTestVariantIsRunning;
|
|
95
|
-
if (!!resp.data.testVariantIsRunning) {
|
|
96
|
-
// If true, set testInfo to the testSession assigned test.
|
|
97
|
-
testInfo = testSession.data;
|
|
98
|
-
}
|
|
99
|
-
else {
|
|
100
|
-
// If not running, clear test session and fetch a new test for the user
|
|
101
|
-
session.set("test", undefined);
|
|
102
|
-
await fetchTestByRulesSetTestinfoAsFirstExposure();
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
if (isUsingCdn) {
|
|
107
|
-
// Return to CDN
|
|
108
|
-
packClient.apiUrl = "https://apicdn.packdigital.com/graphql";
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
return testInfo;
|
|
112
|
-
}
|
|
113
|
-
export function getTestSession(session, testFromQueryParams, previewEnabled) {
|
|
114
|
-
if (testFromQueryParams) {
|
|
115
|
-
return {
|
|
116
|
-
id: testFromQueryParams.testId || "",
|
|
117
|
-
handle: testFromQueryParams.testHandle || "",
|
|
118
|
-
testVariant: {
|
|
119
|
-
id: testFromQueryParams.testVariantId || "",
|
|
120
|
-
handle: testFromQueryParams.testVariantHandle || "",
|
|
121
|
-
},
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
if (previewEnabled) {
|
|
125
|
-
return {
|
|
126
|
-
id: "",
|
|
127
|
-
handle: "isPreview",
|
|
128
|
-
testVariant: {
|
|
129
|
-
id: "",
|
|
130
|
-
handle: "isPreview",
|
|
131
|
-
},
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
if (!session) {
|
|
135
|
-
return undefined;
|
|
136
|
-
}
|
|
137
|
-
const testSession = session.get("test");
|
|
138
|
-
return testSession?.data || null;
|
|
139
|
-
}
|
|
140
|
-
export function getTestTargetingAttributesFromRequest(request) {
|
|
141
|
-
let testTargetingAttributes = {};
|
|
142
|
-
const requestUrl = new URL(request.url);
|
|
143
|
-
const searchParams = requestUrl.searchParams;
|
|
144
|
-
testTargetingAttributes.url = requestUrl.origin + requestUrl.pathname;
|
|
145
|
-
testTargetingAttributes.query = requestUrl.search;
|
|
146
|
-
testTargetingAttributes.path = requestUrl.pathname;
|
|
147
|
-
searchParams.has("utm_campaign") &&
|
|
148
|
-
(testTargetingAttributes.utmCampaign =
|
|
149
|
-
searchParams.get("utm_campaign") || undefined);
|
|
150
|
-
searchParams.has("utm_content") &&
|
|
151
|
-
(testTargetingAttributes.utmContent =
|
|
152
|
-
searchParams.get("utm_content") || undefined);
|
|
153
|
-
searchParams.has("utm_medium") &&
|
|
154
|
-
(testTargetingAttributes.utmMedium =
|
|
155
|
-
searchParams.get("utm_medium") || undefined);
|
|
156
|
-
searchParams.has("utm_source") &&
|
|
157
|
-
(testTargetingAttributes.utmSource =
|
|
158
|
-
searchParams.get("utm_source") || undefined);
|
|
159
|
-
searchParams.has("utm_term") &&
|
|
160
|
-
(testTargetingAttributes.utmTerm =
|
|
161
|
-
searchParams.get("utm_term") || undefined);
|
|
162
|
-
return testTargetingAttributes;
|
|
163
|
-
}
|
|
164
|
-
export function getTestFromQueryParams(request) {
|
|
165
|
-
const requestUrl = new URL(request.url);
|
|
166
|
-
const params = requestUrl.searchParams;
|
|
167
|
-
if (params.has("testId") ||
|
|
168
|
-
params.has("test_id") ||
|
|
169
|
-
params.has("test-id") ||
|
|
170
|
-
params.has("testHandle") ||
|
|
171
|
-
params.has("test_handle") ||
|
|
172
|
-
params.has("test-handle") ||
|
|
173
|
-
params.has("testVariantId") ||
|
|
174
|
-
params.has("test_variant_id") ||
|
|
175
|
-
params.has("test-variant-id") ||
|
|
176
|
-
params.has("testVariantHandle") ||
|
|
177
|
-
params.has("test_variant_handle") ||
|
|
178
|
-
params.has("test-variant-handle")) {
|
|
179
|
-
return {
|
|
180
|
-
testId: params.get("testId") ||
|
|
181
|
-
params.get("test_id") ||
|
|
182
|
-
params.get("test-id") ||
|
|
183
|
-
"",
|
|
184
|
-
testHandle: params.get("testHandle") ||
|
|
185
|
-
params.get("test_handle") ||
|
|
186
|
-
params.get("test-handle") ||
|
|
187
|
-
"",
|
|
188
|
-
testVariantId: params.get("testVariantId") ||
|
|
189
|
-
params.get("test_variant_id") ||
|
|
190
|
-
params.get("test-variant-id") ||
|
|
191
|
-
"",
|
|
192
|
-
testVariantHandle: params.get("testVariantHandle") ||
|
|
193
|
-
params.get("test_variant_handle") ||
|
|
194
|
-
params.get("test-variant-handle") ||
|
|
195
|
-
"",
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
return null;
|
|
199
|
-
}
|
|
200
|
-
export function setTestHeaders(headers, options) {
|
|
201
|
-
const { previewEnabled, testFromQueryParams, testInfoForRequest } = options;
|
|
202
|
-
if (previewEnabled) {
|
|
203
|
-
return headers;
|
|
204
|
-
}
|
|
205
|
-
if (testFromQueryParams) {
|
|
206
|
-
headers["X-Pack-Test-Ignore-Test-Status"] = true;
|
|
207
|
-
if (testFromQueryParams.testId) {
|
|
208
|
-
headers["X-Pack-Test-Id"] = testFromQueryParams.testId;
|
|
209
|
-
}
|
|
210
|
-
if (testFromQueryParams.testHandle) {
|
|
211
|
-
headers["X-Pack-Test-Handle"] = testFromQueryParams.testHandle;
|
|
212
|
-
}
|
|
213
|
-
if (testFromQueryParams.testVariantId) {
|
|
214
|
-
headers["X-Pack-Test-Variant-Id"] = testFromQueryParams.testVariantId;
|
|
215
|
-
}
|
|
216
|
-
if (testFromQueryParams.testVariantHandle) {
|
|
217
|
-
headers["X-Pack-Test-Variant-Handle"] =
|
|
218
|
-
testFromQueryParams.testVariantHandle;
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
else if (testInfoForRequest) {
|
|
222
|
-
headers = {
|
|
223
|
-
"X-Pack-Test-Id": testInfoForRequest?.id,
|
|
224
|
-
"X-Pack-Test-Variant-Id": testInfoForRequest?.testVariant?.id,
|
|
225
|
-
};
|
|
226
|
-
}
|
|
227
|
-
return headers;
|
|
228
|
-
}
|