@pack/hydrogen 1.0.4 → 1.0.6-ab-test.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/dist/create-pack-client.d.ts +29 -5
- package/dist/create-pack-client.d.ts.map +1 -1
- package/dist/create-pack-client.js +102 -31
- package/dist/handle-request.d.ts.map +1 -1
- package/dist/handle-request.js +2 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/preview/preview-mode.d.ts.map +1 -1
- package/dist/preview/preview-mode.js +3 -1
- package/dist/session/cookies-utils.js +1 -1
- package/dist/tests/test.d.ts.map +1 -1
- package/dist/tests/test.js +75 -85
- package/package.json +6 -3
|
@@ -2,6 +2,7 @@
|
|
|
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";
|
|
5
6
|
/** @see https://shopify.dev/docs/custom-storefronts/hydrogen/data-fetching/cache#caching-strategies */
|
|
6
7
|
type CachingStrategy = ReturnType<typeof CacheCustom>;
|
|
7
8
|
interface EnvironmentOptions {
|
|
@@ -16,7 +17,7 @@ interface EnvironmentOptions {
|
|
|
16
17
|
*/
|
|
17
18
|
waitUntil: ExecutionContext["waitUntil"];
|
|
18
19
|
}
|
|
19
|
-
interface CreatePackClientOptions extends EnvironmentOptions {
|
|
20
|
+
export interface CreatePackClientOptions extends EnvironmentOptions {
|
|
20
21
|
apiUrl?: string;
|
|
21
22
|
token?: string;
|
|
22
23
|
storeId?: string;
|
|
@@ -29,6 +30,7 @@ type Variables = Record<string, any>;
|
|
|
29
30
|
interface QueryOptions {
|
|
30
31
|
variables?: Variables;
|
|
31
32
|
cache?: CachingStrategy;
|
|
33
|
+
test?: TestInput;
|
|
32
34
|
}
|
|
33
35
|
interface QueryError {
|
|
34
36
|
message: string;
|
|
@@ -39,18 +41,40 @@ interface QueryError {
|
|
|
39
41
|
interface QueryResponse<T> {
|
|
40
42
|
data: T | null;
|
|
41
43
|
error: QueryError | null;
|
|
44
|
+
packTestInfo?: Test;
|
|
45
|
+
}
|
|
46
|
+
export interface PackCustomizerMeta {
|
|
47
|
+
environment?: string;
|
|
48
|
+
overlay?: {
|
|
49
|
+
src?: string;
|
|
50
|
+
version?: string;
|
|
51
|
+
};
|
|
52
|
+
[key: string]: any;
|
|
42
53
|
}
|
|
43
54
|
export interface Pack {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
55
|
+
abTest: Test | null | undefined;
|
|
56
|
+
/**
|
|
57
|
+
* @deprecated The method should not be used
|
|
58
|
+
*/
|
|
48
59
|
getPackSessionData(): {
|
|
49
60
|
storeId: string;
|
|
50
61
|
sessionId: string;
|
|
62
|
+
abTest: Test | null | undefined;
|
|
51
63
|
isPreviewModeEnabled: boolean;
|
|
52
64
|
customizerMeta: any;
|
|
53
65
|
};
|
|
66
|
+
getPackContextData(): {
|
|
67
|
+
packStoreId: string;
|
|
68
|
+
packSessionId: string;
|
|
69
|
+
packAbTest: Test | null | undefined;
|
|
70
|
+
packIsPreviewMode: boolean;
|
|
71
|
+
packCustomizerMeta: PackCustomizerMeta | null;
|
|
72
|
+
};
|
|
73
|
+
handleRequest(request: Request): Promise<(response: Response) => void>;
|
|
74
|
+
isPreviewModeEnabled: () => boolean;
|
|
75
|
+
isValidEditToken: PackClient["isValidEditToken"];
|
|
76
|
+
query: <T = any>(query: string, options?: QueryOptions) => Promise<QueryResponse<T>>;
|
|
77
|
+
session: PackSession;
|
|
54
78
|
}
|
|
55
79
|
interface DefaultThemeData {
|
|
56
80
|
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":"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"}
|
|
@@ -1,5 +1,7 @@
|
|
|
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";
|
|
3
5
|
/**
|
|
4
6
|
* Create an SHA-256 hash as a hex string
|
|
5
7
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest#converting_a_digest_to_a_hex_string
|
|
@@ -113,16 +115,70 @@ export function createPackClient(options) {
|
|
|
113
115
|
const previewEnabled = !!session.get("previewEnabled");
|
|
114
116
|
const previewEnvironment = session.get("environment");
|
|
115
117
|
const clientContentEnvironment = previewEnvironment || contentEnvironment;
|
|
118
|
+
let packClient;
|
|
119
|
+
let testFromQueryParams = null;
|
|
120
|
+
let testInfoForRequest = undefined;
|
|
116
121
|
if (!token && !defaultThemeData) {
|
|
117
122
|
throw new Error("The Pack client token is missing or empty. Please provide a valid token or default theme data.");
|
|
118
123
|
}
|
|
119
124
|
if (!storeId) {
|
|
120
125
|
throw new Error("The Pack Store ID is missing or empty. Please provide a valid Store ID.");
|
|
121
126
|
}
|
|
127
|
+
const handleRequest = async (request) => {
|
|
128
|
+
testFromQueryParams = getTestFromQueryParams(request);
|
|
129
|
+
const testTargetAudienceAttributes = getTestTargetingAttributesFromRequest(request);
|
|
130
|
+
if (packClient) {
|
|
131
|
+
testInfoForRequest = await getTestInfo({
|
|
132
|
+
request,
|
|
133
|
+
testTargetAudienceAttributes,
|
|
134
|
+
packClient,
|
|
135
|
+
session,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
return (response) => {
|
|
139
|
+
const hasExposedTestCookie = request.headers
|
|
140
|
+
.get("cookie")
|
|
141
|
+
?.includes("exposedTest");
|
|
142
|
+
if (hasExposedTestCookie) {
|
|
143
|
+
// Clear the exposedTest cookie
|
|
144
|
+
response.headers.set("Set-Cookie", cookie.serialize("exposedTest", "", {
|
|
145
|
+
maxAge: 0,
|
|
146
|
+
}));
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
};
|
|
150
|
+
const getTestInfoForLoader = () => {
|
|
151
|
+
let testInfoForLoader = undefined;
|
|
152
|
+
if (testInfoForRequest?.isFirstExposure) {
|
|
153
|
+
const { isFirstExposure, ...testInfo } = testInfoForRequest;
|
|
154
|
+
testInfoForLoader = testInfo;
|
|
155
|
+
}
|
|
156
|
+
return testInfoForLoader;
|
|
157
|
+
};
|
|
122
158
|
if (!token) {
|
|
123
159
|
return {
|
|
124
|
-
session,
|
|
160
|
+
abTest: getTestSession(session, testFromQueryParams, previewEnabled),
|
|
161
|
+
handleRequest,
|
|
162
|
+
getPackSessionData: () => {
|
|
163
|
+
return {
|
|
164
|
+
storeId: storeId,
|
|
165
|
+
sessionId: session.id,
|
|
166
|
+
abTest: getTestSession(session, testFromQueryParams, previewEnabled),
|
|
167
|
+
isPreviewModeEnabled: previewEnabled,
|
|
168
|
+
customizerMeta: session.get("customizerMeta"),
|
|
169
|
+
};
|
|
170
|
+
},
|
|
171
|
+
getPackContextData: () => {
|
|
172
|
+
return {
|
|
173
|
+
packStoreId: storeId,
|
|
174
|
+
packSessionId: session.id,
|
|
175
|
+
packAbTest: getTestSession(session, testFromQueryParams, previewEnabled),
|
|
176
|
+
packIsPreviewMode: previewEnabled,
|
|
177
|
+
packCustomizerMeta: session.get("customizerMeta"),
|
|
178
|
+
};
|
|
179
|
+
},
|
|
125
180
|
isPreviewModeEnabled: () => previewEnabled,
|
|
181
|
+
isValidEditToken: () => new Promise(() => false),
|
|
126
182
|
async query(query, { variables } = {}) {
|
|
127
183
|
if (!defaultThemeData?.data) {
|
|
128
184
|
console.warn("Invalid default theme data provided to Pack client.");
|
|
@@ -131,18 +187,10 @@ export function createPackClient(options) {
|
|
|
131
187
|
const data = resolveQuery({ query, variables, defaultThemeData });
|
|
132
188
|
return { data: data, error: null };
|
|
133
189
|
},
|
|
134
|
-
|
|
135
|
-
getPackSessionData: () => {
|
|
136
|
-
return {
|
|
137
|
-
storeId: storeId,
|
|
138
|
-
sessionId: session.id,
|
|
139
|
-
isPreviewModeEnabled: previewEnabled,
|
|
140
|
-
customizerMeta: session.get("customizerMeta"),
|
|
141
|
-
};
|
|
142
|
-
},
|
|
190
|
+
session,
|
|
143
191
|
};
|
|
144
192
|
}
|
|
145
|
-
|
|
193
|
+
packClient = new PackClient({
|
|
146
194
|
// Use apiUrl, it is configured
|
|
147
195
|
// Use active API URL if preview mode is enabled
|
|
148
196
|
// Otherwise, Live PackClient uses its internal configuration
|
|
@@ -157,16 +205,40 @@ export function createPackClient(options) {
|
|
|
157
205
|
sessionId: session.id,
|
|
158
206
|
clientName: "HydrogenClient",
|
|
159
207
|
});
|
|
160
|
-
console.log("*** packClient.apiUrl", packClient.apiUrl);
|
|
161
208
|
return {
|
|
162
|
-
session,
|
|
209
|
+
abTest: getTestSession(session, testFromQueryParams, previewEnabled),
|
|
210
|
+
getPackSessionData: () => {
|
|
211
|
+
return {
|
|
212
|
+
storeId: storeId,
|
|
213
|
+
sessionId: session.id,
|
|
214
|
+
abTest: getTestSession(session, testFromQueryParams, previewEnabled),
|
|
215
|
+
isPreviewModeEnabled: previewEnabled,
|
|
216
|
+
customizerMeta: session.get("customizerMeta"),
|
|
217
|
+
};
|
|
218
|
+
},
|
|
219
|
+
getPackContextData: () => {
|
|
220
|
+
return {
|
|
221
|
+
packStoreId: storeId,
|
|
222
|
+
packSessionId: session.id,
|
|
223
|
+
packAbTest: getTestSession(session, testFromQueryParams, previewEnabled),
|
|
224
|
+
packIsPreviewMode: previewEnabled,
|
|
225
|
+
packCustomizerMeta: session.get("customizerMeta"),
|
|
226
|
+
};
|
|
227
|
+
},
|
|
228
|
+
handleRequest,
|
|
163
229
|
isPreviewModeEnabled: () => previewEnabled,
|
|
164
|
-
|
|
230
|
+
isValidEditToken: (token) => packClient.isValidEditToken(token),
|
|
231
|
+
async query(query, { variables, cache: strategy = cacheCustom, test } = {}) {
|
|
232
|
+
let headers = {};
|
|
165
233
|
const withCache = createWithCache({
|
|
166
234
|
cache,
|
|
167
235
|
waitUntil,
|
|
168
236
|
});
|
|
169
|
-
|
|
237
|
+
headers = setTestHeaders(headers, {
|
|
238
|
+
previewEnabled,
|
|
239
|
+
testInfoForRequest,
|
|
240
|
+
testFromQueryParams: testFromQueryParams || test,
|
|
241
|
+
});
|
|
170
242
|
const queryVariables = variables ? { ...variables } : {};
|
|
171
243
|
if (previewEnabled) {
|
|
172
244
|
queryVariables.version = "CURRENT";
|
|
@@ -174,23 +246,27 @@ export function createPackClient(options) {
|
|
|
174
246
|
else {
|
|
175
247
|
queryVariables.version = "PUBLISHED";
|
|
176
248
|
}
|
|
249
|
+
const testInfoForLoader = getTestInfoForLoader();
|
|
177
250
|
// Preview mode always bypasses the cache
|
|
178
251
|
if (previewEnabled) {
|
|
179
252
|
try {
|
|
180
|
-
return
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
253
|
+
return {
|
|
254
|
+
...(await packClient.fetch(query, {
|
|
255
|
+
variables: queryVariables,
|
|
256
|
+
headers: headers,
|
|
257
|
+
})),
|
|
258
|
+
packTestInfo: testInfoForLoader,
|
|
259
|
+
};
|
|
184
260
|
}
|
|
185
261
|
catch (error) {
|
|
186
|
-
return { error, data:
|
|
262
|
+
return { error: error, data: null };
|
|
187
263
|
}
|
|
188
264
|
}
|
|
189
265
|
const queryHash = await getCacheKey(withCache, query, token, {
|
|
190
266
|
variables: queryVariables,
|
|
191
267
|
headers,
|
|
192
268
|
});
|
|
193
|
-
|
|
269
|
+
const response = await withCache(queryHash, strategy, async () => {
|
|
194
270
|
try {
|
|
195
271
|
return await packClient.fetch(query, {
|
|
196
272
|
variables: queryVariables,
|
|
@@ -198,18 +274,13 @@ export function createPackClient(options) {
|
|
|
198
274
|
});
|
|
199
275
|
}
|
|
200
276
|
catch (error) {
|
|
201
|
-
return { error, data:
|
|
277
|
+
return { error, data: null };
|
|
202
278
|
}
|
|
203
279
|
});
|
|
280
|
+
return response.error
|
|
281
|
+
? response
|
|
282
|
+
: { ...response, packTestInfo: testInfoForLoader };
|
|
204
283
|
},
|
|
205
|
-
|
|
206
|
-
getPackSessionData: () => {
|
|
207
|
-
return {
|
|
208
|
-
storeId: storeId,
|
|
209
|
-
sessionId: session.id,
|
|
210
|
-
isPreviewModeEnabled: previewEnabled,
|
|
211
|
-
customizerMeta: session.get("customizerMeta"),
|
|
212
|
-
};
|
|
213
|
-
},
|
|
284
|
+
session,
|
|
214
285
|
};
|
|
215
286
|
}
|
|
@@ -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,8 +1,10 @@
|
|
|
1
1
|
import { packlytics } from "@pack/packlytics";
|
|
2
2
|
export async function handleRequest(pack, request, handleRequest) {
|
|
3
|
+
const packHandleResponse = await pack.handleRequest(request);
|
|
3
4
|
const response = await packlytics(pack, request, () => {
|
|
4
5
|
return handleRequest(request);
|
|
5
6
|
});
|
|
7
|
+
packHandleResponse(response);
|
|
6
8
|
response.headers.append("powered-by", "Shopify, Hydrogen + Pack Digital");
|
|
7
9
|
response.headers.append("Set-Cookie", await pack.session.commit());
|
|
8
10
|
return response;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { handleRequest } from "./handle-request";
|
|
2
2
|
import { usePackCookies } from "./session/usePackCookies";
|
|
3
3
|
import { PackSession } from "./session/session";
|
|
4
|
-
import { createPackClient } from "./create-pack-client";
|
|
4
|
+
import { Pack, createPackClient } from "./create-pack-client";
|
|
5
5
|
import { action as previewModeAction, loader as previewModeLoader } from "./preview/preview-mode";
|
|
6
|
-
|
|
6
|
+
import { PackTestContext, usePackTestContext, PackTestProvider, PackTestRoute, useAbTest, useAbTestId, useAbTestHandle, useAbTestSessionId, useAbTestVariantId, useAbTestVariantHandle } from "./tests";
|
|
7
|
+
export type { Pack };
|
|
8
|
+
export { PackSession, createPackClient, handleRequest, previewModeAction, previewModeLoader, usePackCookies, PackTestContext, usePackTestContext, PackTestProvider, PackTestRoute, useAbTest, useAbTestId, useAbTestHandle, useAbTestSessionId, useAbTestVariantId, useAbTestVariantHandle, };
|
|
7
9
|
//# 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;
|
|
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,IAAI,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EACL,MAAM,IAAI,iBAAiB,EAC3B,MAAM,IAAI,iBAAiB,EAC5B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,EACb,SAAS,EACT,WAAW,EACX,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,sBAAsB,EACvB,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,IAAI,EAAE,CAAC;AAErB,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,EACb,SAAS,EACT,WAAW,EACX,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,sBAAsB,GACvB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -3,4 +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
|
-
|
|
6
|
+
import { PackTestContext, usePackTestContext, PackTestProvider, PackTestRoute, useAbTest, useAbTestId, useAbTestHandle, useAbTestSessionId, useAbTestVariantId, useAbTestVariantHandle, } from "./tests";
|
|
7
|
+
export { PackSession, createPackClient, handleRequest, previewModeAction, previewModeLoader, usePackCookies, PackTestContext, usePackTestContext, PackTestProvider, PackTestRoute, useAbTest, useAbTestId, useAbTestHandle, useAbTestSessionId, useAbTestVariantId, useAbTestVariantHandle, };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preview-mode.d.ts","sourceRoot":"","sources":["../../src/preview/preview-mode.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"preview-mode.d.ts","sourceRoot":"","sources":["../../src/preview/preview-mode.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAKnC,KAAK,YAAY,GAAG,CAAC,IAAI,EACvB,IAAI,EAAE,IAAI,EACV,IAAI,CAAC,EAAE,MAAM,GAAG,YAAY,KACzB,aAAa,CAAC,IAAI,CAAC,CAAC;AAEzB,KAAK,gBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,YAAY,KAAK,QAAQ,CAAC;AAIhF,KAAK,aAAa,CAAC,CAAC,GAAG,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG;IACzD,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;CACpB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,IAAI,EAAE,YAYlB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,QAAQ,EAAE,gBAetB,CAAC;AAoBF;;;GAGG;AACH,eAAO,MAAM,MAAM,EAAE,cAkBpB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,MAAM,EAAE,cA0CpB,CAAC"}
|
|
@@ -88,7 +88,9 @@ export const loader = async function ({ request, context }) {
|
|
|
88
88
|
}
|
|
89
89
|
let customizerMetaJson;
|
|
90
90
|
try {
|
|
91
|
-
customizerMetaJson = customizerMeta
|
|
91
|
+
customizerMetaJson = customizerMeta
|
|
92
|
+
? JSON.parse(customizerMeta)
|
|
93
|
+
: null;
|
|
92
94
|
}
|
|
93
95
|
catch (_error) {
|
|
94
96
|
customizerMetaJson = null;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PACK_USER_CONSENT_COOKIE_ID } from "../constants";
|
|
2
|
-
|
|
2
|
+
import cookie from "cookie";
|
|
3
3
|
const tokenHash = "xxxx-4xxx-xxxx-xxxxxxxxxxxx";
|
|
4
4
|
export function hasUserConsent(request) {
|
|
5
5
|
const cookies = cookie.parse(request.headers.get("Cookie"));
|
package/dist/tests/test.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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;
|
|
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;AA+DD,wBAAsB,WAAW,CAAC,EAChC,OAAO,EACP,4BAA4B,EAC5B,UAAU,EACV,OAAO,GACR,EAAE,kBAAkB,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CA4DpD;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,OA+BF"}
|
package/dist/tests/test.js
CHANGED
|
@@ -16,99 +16,89 @@ const QUERY_TEST_VARIANT_IS_RUNNING = `#graphql
|
|
|
16
16
|
testVariantIsRunning(handle: $handle, testId: $testId)
|
|
17
17
|
}
|
|
18
18
|
`;
|
|
19
|
-
|
|
20
|
-
let
|
|
21
|
-
if
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const packClientFetchTestByRules = packClient.fetch(QUERY_TEST_BY_RULES, {
|
|
19
|
+
async function packClientFetchTestByRules(packClient, testTargetAudienceAttributes) {
|
|
20
|
+
let resp = undefined;
|
|
21
|
+
// Check if are using CDN or a custom endpoint if so
|
|
22
|
+
// Request directly to API if it is using CDN to reduce latency
|
|
23
|
+
const isUsingCdn = packClient.apiUrl === "https://apicdn.packdigital.com/graphql";
|
|
24
|
+
if (isUsingCdn) {
|
|
25
|
+
packClient.apiUrl = "https://app.packdigital.com/graphql";
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
const packClientFetchTestByRules = await packClient.fetch(QUERY_TEST_BY_RULES, {
|
|
29
29
|
variables: {
|
|
30
30
|
testTargetAudienceAttributes,
|
|
31
31
|
},
|
|
32
32
|
});
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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
|
-
}
|
|
33
|
+
if (packClientFetchTestByRules.data?.testByRules) {
|
|
34
|
+
resp = {
|
|
35
|
+
...packClientFetchTestByRules.data?.testByRules,
|
|
36
|
+
isFirstExposure: true,
|
|
37
|
+
};
|
|
79
38
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
39
|
+
}
|
|
40
|
+
catch (e) {
|
|
41
|
+
console.error(e);
|
|
42
|
+
}
|
|
43
|
+
// Return to CDN
|
|
44
|
+
if (isUsingCdn) {
|
|
45
|
+
packClient.apiUrl = "https://apicdn.packdigital.com/graphql";
|
|
46
|
+
}
|
|
47
|
+
return resp;
|
|
48
|
+
}
|
|
49
|
+
async function packClientCheckTestIsRunning(packClient, testSession) {
|
|
50
|
+
try {
|
|
51
|
+
const resp = await packClient.fetch(QUERY_TEST_VARIANT_IS_RUNNING, {
|
|
52
|
+
variables: {
|
|
53
|
+
handle: testSession.testVariant.handle,
|
|
54
|
+
testId: testSession.id,
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
return !!resp.data.testVariantIsRunning;
|
|
58
|
+
}
|
|
59
|
+
catch (e) {
|
|
60
|
+
console.error(e);
|
|
61
|
+
}
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
export async function getTestInfo({ request, testTargetAudienceAttributes, packClient, session, }) {
|
|
65
|
+
let testInfo = undefined;
|
|
66
|
+
let exposedTest = undefined;
|
|
67
|
+
if (!session) {
|
|
68
|
+
return testInfo;
|
|
69
|
+
}
|
|
70
|
+
const testSession = session.get("test");
|
|
71
|
+
const exposedTestCookieString = cookie.parse(request.headers.get("cookie") || "")?.exposedTest;
|
|
72
|
+
if (exposedTestCookieString) {
|
|
73
|
+
exposedTest = JSON.parse(exposedTestCookieString);
|
|
74
|
+
}
|
|
75
|
+
// If there is test on session, check if the test on session is still running.
|
|
76
|
+
if (testSession && testSession.data?.id && testSession.data?.testVariant) {
|
|
77
|
+
const testVariantIsRunning = await packClientCheckTestIsRunning(packClient, testSession.data);
|
|
78
|
+
// If true, set testInfo to the testSession assigned test.
|
|
79
|
+
if (testVariantIsRunning) {
|
|
80
|
+
testInfo = testSession.data;
|
|
106
81
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
82
|
+
}
|
|
83
|
+
else if (exposedTest) {
|
|
84
|
+
// If there is no assigned test on the session and an exposed test in the
|
|
85
|
+
// incoming request cookie it means that the user was exposed to a test previously.
|
|
86
|
+
// Verify test is still running
|
|
87
|
+
const testVariantIsRunning = await packClientCheckTestIsRunning(packClient, exposedTest);
|
|
88
|
+
// If the test is still running, set testInfo to the exposed test
|
|
89
|
+
if (testVariantIsRunning) {
|
|
90
|
+
testInfo = exposedTest;
|
|
110
91
|
}
|
|
111
92
|
}
|
|
93
|
+
// If the testInfo is not setup that means that is not a valid test
|
|
94
|
+
// on the session or on the cookie, then fetch a new test for the user
|
|
95
|
+
if (!testInfo) {
|
|
96
|
+
testInfo = await packClientFetchTestByRules(packClient, testTargetAudienceAttributes);
|
|
97
|
+
}
|
|
98
|
+
// save this test on the session
|
|
99
|
+
session.set("test", {
|
|
100
|
+
data: testInfo,
|
|
101
|
+
});
|
|
112
102
|
return testInfo;
|
|
113
103
|
}
|
|
114
104
|
export function getTestSession(session, testFromQueryParams, previewEnabled) {
|
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.6-ab-test.0",
|
|
5
5
|
"exports": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
7
7
|
"engines": {
|
|
@@ -22,14 +22,17 @@
|
|
|
22
22
|
"dist"
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@pack/client": "^1.0.1",
|
|
25
|
+
"@pack/client": "^1.0.1-ab-test.0",
|
|
26
26
|
"@pack/packlytics": "^1.0.1",
|
|
27
|
-
"@shopify/hydrogen": "^2023.10.2"
|
|
27
|
+
"@shopify/hydrogen": "^2023.10.2",
|
|
28
|
+
"cookie": "^0.6.0",
|
|
29
|
+
"js-cookie": "^3.0.5"
|
|
28
30
|
},
|
|
29
31
|
"devDependencies": {
|
|
30
32
|
"@remix-run/server-runtime": "^2.0.0",
|
|
31
33
|
"@shopify/oxygen-workers-types": "^4.0.0",
|
|
32
34
|
"@shopify/remix-oxygen": "^2.0.1",
|
|
35
|
+
"@types/js-cookie": "^3.0.6",
|
|
33
36
|
"@types/node": "^20.11.17"
|
|
34
37
|
},
|
|
35
38
|
"peerDependencies": {
|