@pack/hydrogen 1.0.5 → 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 -30
- 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":";AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAmB,MAAM,mBAAmB,CAAC;AAEjE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAML,IAAI,EACJ,SAAS,EAGV,MAAM,cAAc,CAAC;AAEtB,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,MAAM,WAAW,uBAAwB,SAAQ,kBAAkB;IACjE,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;IACxB,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;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;IACzB,YAAY,CAAC,EAAE,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE;QACR,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,IAAI;IACnB,MAAM,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,CAAC;IAChC;;OAEG;IACH,kBAAkB,IAAI;QACpB,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,CAAC;QAChC,oBAAoB,EAAE,OAAO,CAAC;QAC9B,cAAc,EAAE,GAAG,CAAC;KACrB,CAAC;IACF,kBAAkB,IAAI;QACpB,WAAW,EAAE,MAAM,CAAC;QACpB,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,CAAC;QACpC,iBAAiB,EAAE,OAAO,CAAC;QAC3B,kBAAkB,EAAE,kBAAkB,GAAG,IAAI,CAAC;KAC/C,CAAC;IACF,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC,CAAC;IACvE,oBAAoB,EAAE,MAAM,OAAO,CAAC;IACpC,gBAAgB,EAAE,UAAU,CAAC,kBAAkB,CAAC,CAAC;IACjD,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,OAAO,EAAE,WAAW,CAAC;CACtB;AAED,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC3B;AAoJD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,IAAI,CAgPvE"}
|
|
@@ -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
|
|
@@ -158,14 +206,39 @@ export function createPackClient(options) {
|
|
|
158
206
|
clientName: "HydrogenClient",
|
|
159
207
|
});
|
|
160
208
|
return {
|
|
161
|
-
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,
|
|
162
229
|
isPreviewModeEnabled: () => previewEnabled,
|
|
163
|
-
|
|
230
|
+
isValidEditToken: (token) => packClient.isValidEditToken(token),
|
|
231
|
+
async query(query, { variables, cache: strategy = cacheCustom, test } = {}) {
|
|
232
|
+
let headers = {};
|
|
164
233
|
const withCache = createWithCache({
|
|
165
234
|
cache,
|
|
166
235
|
waitUntil,
|
|
167
236
|
});
|
|
168
|
-
|
|
237
|
+
headers = setTestHeaders(headers, {
|
|
238
|
+
previewEnabled,
|
|
239
|
+
testInfoForRequest,
|
|
240
|
+
testFromQueryParams: testFromQueryParams || test,
|
|
241
|
+
});
|
|
169
242
|
const queryVariables = variables ? { ...variables } : {};
|
|
170
243
|
if (previewEnabled) {
|
|
171
244
|
queryVariables.version = "CURRENT";
|
|
@@ -173,23 +246,27 @@ export function createPackClient(options) {
|
|
|
173
246
|
else {
|
|
174
247
|
queryVariables.version = "PUBLISHED";
|
|
175
248
|
}
|
|
249
|
+
const testInfoForLoader = getTestInfoForLoader();
|
|
176
250
|
// Preview mode always bypasses the cache
|
|
177
251
|
if (previewEnabled) {
|
|
178
252
|
try {
|
|
179
|
-
return
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
253
|
+
return {
|
|
254
|
+
...(await packClient.fetch(query, {
|
|
255
|
+
variables: queryVariables,
|
|
256
|
+
headers: headers,
|
|
257
|
+
})),
|
|
258
|
+
packTestInfo: testInfoForLoader,
|
|
259
|
+
};
|
|
183
260
|
}
|
|
184
261
|
catch (error) {
|
|
185
|
-
return { error, data:
|
|
262
|
+
return { error: error, data: null };
|
|
186
263
|
}
|
|
187
264
|
}
|
|
188
265
|
const queryHash = await getCacheKey(withCache, query, token, {
|
|
189
266
|
variables: queryVariables,
|
|
190
267
|
headers,
|
|
191
268
|
});
|
|
192
|
-
|
|
269
|
+
const response = await withCache(queryHash, strategy, async () => {
|
|
193
270
|
try {
|
|
194
271
|
return await packClient.fetch(query, {
|
|
195
272
|
variables: queryVariables,
|
|
@@ -197,18 +274,13 @@ export function createPackClient(options) {
|
|
|
197
274
|
});
|
|
198
275
|
}
|
|
199
276
|
catch (error) {
|
|
200
|
-
return { error, data:
|
|
277
|
+
return { error, data: null };
|
|
201
278
|
}
|
|
202
279
|
});
|
|
280
|
+
return response.error
|
|
281
|
+
? response
|
|
282
|
+
: { ...response, packTestInfo: testInfoForLoader };
|
|
203
283
|
},
|
|
204
|
-
|
|
205
|
-
getPackSessionData: () => {
|
|
206
|
-
return {
|
|
207
|
-
storeId: storeId,
|
|
208
|
-
sessionId: session.id,
|
|
209
|
-
isPreviewModeEnabled: previewEnabled,
|
|
210
|
-
customizerMeta: session.get("customizerMeta"),
|
|
211
|
-
};
|
|
212
|
-
},
|
|
284
|
+
session,
|
|
213
285
|
};
|
|
214
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": {
|