@pack/hydrogen 1.0.6-ab-test.9 → 1.0.7
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 -29
- package/dist/create-pack-client.d.ts.map +1 -1
- package/dist/create-pack-client.js +32 -105
- package/dist/handle-request.d.ts.map +1 -1
- package/dist/handle-request.js +0 -2
- package/dist/index.d.ts +2 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -2
- package/dist/preview/preview-mode.d.ts.map +1 -1
- package/dist/preview/preview-mode.js +1 -3
- package/dist/session/session.d.ts.map +1 -1
- package/dist/session/session.js +1 -14
- package/package.json +3 -6
- 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 -23
- 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 -9
- package/dist/tests/pack-test-provider.d.ts.map +0 -1
- package/dist/tests/pack-test-provider.js +0 -15
- 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 -79
- package/dist/tests/test.d.ts +0 -46
- package/dist/tests/test.d.ts.map +0 -1
- package/dist/tests/test.js +0 -252
|
@@ -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,40 +39,18 @@ interface QueryError {
|
|
|
41
39
|
interface QueryResponse<T> {
|
|
42
40
|
data: T | null;
|
|
43
41
|
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;
|
|
53
42
|
}
|
|
54
43
|
export interface Pack {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
44
|
+
isPreviewModeEnabled: () => boolean;
|
|
45
|
+
session: PackSession;
|
|
46
|
+
query: <T = any>(query: string, options?: QueryOptions) => Promise<QueryResponse<T>>;
|
|
47
|
+
isValidEditToken: PackClient["isValidEditToken"];
|
|
59
48
|
getPackSessionData(): {
|
|
60
49
|
storeId: string;
|
|
61
50
|
sessionId: string;
|
|
62
|
-
abTest: Test | null | undefined;
|
|
63
51
|
isPreviewModeEnabled: boolean;
|
|
64
52
|
customizerMeta: any;
|
|
65
53
|
};
|
|
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;
|
|
78
54
|
}
|
|
79
55
|
interface DefaultThemeData {
|
|
80
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
|
|
@@ -115,71 +113,16 @@ export function createPackClient(options) {
|
|
|
115
113
|
const previewEnabled = !!session.get("previewEnabled");
|
|
116
114
|
const previewEnvironment = session.get("environment");
|
|
117
115
|
const clientContentEnvironment = previewEnvironment || contentEnvironment;
|
|
118
|
-
let packClient;
|
|
119
|
-
let testFromQueryParams = null;
|
|
120
|
-
let testInfoForRequest = undefined;
|
|
121
116
|
if (!token && !defaultThemeData) {
|
|
122
|
-
throw new Error("
|
|
117
|
+
throw new Error("The Pack client token is missing or empty. Please provide a valid token or default theme data.");
|
|
123
118
|
}
|
|
124
119
|
if (!storeId) {
|
|
125
|
-
throw new Error("
|
|
120
|
+
throw new Error("The Pack Store ID is missing or empty. Please provide a valid Store ID.");
|
|
126
121
|
}
|
|
127
|
-
const handleRequest = async (request) => {
|
|
128
|
-
testFromQueryParams = getTestFromQueryParams(request);
|
|
129
|
-
const testTargetAudienceAttributes = getTestTargetingAttributesFromRequest(request);
|
|
130
|
-
if (packClient && token) {
|
|
131
|
-
testInfoForRequest = await getTestInfo({
|
|
132
|
-
request,
|
|
133
|
-
testTargetAudienceAttributes,
|
|
134
|
-
packClient,
|
|
135
|
-
session,
|
|
136
|
-
token,
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
return (response) => {
|
|
140
|
-
const hasExposedTestCookie = request.headers
|
|
141
|
-
.get("cookie")
|
|
142
|
-
?.includes("exposedTest");
|
|
143
|
-
if (hasExposedTestCookie) {
|
|
144
|
-
// Clear the exposedTest cookie
|
|
145
|
-
response.headers.set("Set-Cookie", cookie.serialize("exposedTest", "", {
|
|
146
|
-
maxAge: 0,
|
|
147
|
-
}));
|
|
148
|
-
}
|
|
149
|
-
};
|
|
150
|
-
};
|
|
151
|
-
const getTestInfoForLoader = () => {
|
|
152
|
-
let testInfoForLoader = undefined;
|
|
153
|
-
if (testInfoForRequest?.isFirstExposure) {
|
|
154
|
-
const { isFirstExposure, ...testInfo } = testInfoForRequest;
|
|
155
|
-
testInfoForLoader = testInfo;
|
|
156
|
-
}
|
|
157
|
-
return testInfoForLoader;
|
|
158
|
-
};
|
|
159
122
|
if (!token) {
|
|
160
123
|
return {
|
|
161
|
-
|
|
162
|
-
handleRequest,
|
|
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
|
-
getPackContextData: () => {
|
|
173
|
-
return {
|
|
174
|
-
packStoreId: storeId,
|
|
175
|
-
packSessionId: session.id,
|
|
176
|
-
packAbTest: getTestSession(session, testFromQueryParams, previewEnabled),
|
|
177
|
-
packIsPreviewMode: previewEnabled,
|
|
178
|
-
packCustomizerMeta: session.get("customizerMeta"),
|
|
179
|
-
};
|
|
180
|
-
},
|
|
124
|
+
session,
|
|
181
125
|
isPreviewModeEnabled: () => previewEnabled,
|
|
182
|
-
isValidEditToken: () => new Promise(() => false),
|
|
183
126
|
async query(query, { variables } = {}) {
|
|
184
127
|
if (!defaultThemeData?.data) {
|
|
185
128
|
console.warn("Invalid default theme data provided to Pack client.");
|
|
@@ -188,10 +131,18 @@ export function createPackClient(options) {
|
|
|
188
131
|
const data = resolveQuery({ query, variables, defaultThemeData });
|
|
189
132
|
return { data: data, error: null };
|
|
190
133
|
},
|
|
191
|
-
|
|
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
|
+
},
|
|
192
143
|
};
|
|
193
144
|
}
|
|
194
|
-
packClient = new PackClient({
|
|
145
|
+
const packClient = new PackClient({
|
|
195
146
|
// Use apiUrl, it is configured
|
|
196
147
|
// Use active API URL if preview mode is enabled
|
|
197
148
|
// Otherwise, Live PackClient uses its internal configuration
|
|
@@ -207,39 +158,14 @@ export function createPackClient(options) {
|
|
|
207
158
|
clientName: "HydrogenClient",
|
|
208
159
|
});
|
|
209
160
|
return {
|
|
210
|
-
|
|
211
|
-
getPackSessionData: () => {
|
|
212
|
-
return {
|
|
213
|
-
storeId: storeId,
|
|
214
|
-
sessionId: session.id,
|
|
215
|
-
abTest: getTestSession(session, testFromQueryParams, previewEnabled),
|
|
216
|
-
isPreviewModeEnabled: previewEnabled,
|
|
217
|
-
customizerMeta: session.get("customizerMeta"),
|
|
218
|
-
};
|
|
219
|
-
},
|
|
220
|
-
getPackContextData: () => {
|
|
221
|
-
return {
|
|
222
|
-
packStoreId: storeId,
|
|
223
|
-
packSessionId: session.id,
|
|
224
|
-
packAbTest: getTestSession(session, testFromQueryParams, previewEnabled),
|
|
225
|
-
packIsPreviewMode: previewEnabled,
|
|
226
|
-
packCustomizerMeta: session.get("customizerMeta"),
|
|
227
|
-
};
|
|
228
|
-
},
|
|
229
|
-
handleRequest,
|
|
161
|
+
session,
|
|
230
162
|
isPreviewModeEnabled: () => previewEnabled,
|
|
231
|
-
|
|
232
|
-
async query(query, { variables, cache: strategy = cacheCustom, test } = {}) {
|
|
233
|
-
let headers = {};
|
|
163
|
+
async query(query, { variables, cache: strategy = cacheCustom } = {}) {
|
|
234
164
|
const withCache = createWithCache({
|
|
235
165
|
cache,
|
|
236
166
|
waitUntil,
|
|
237
167
|
});
|
|
238
|
-
headers =
|
|
239
|
-
previewEnabled,
|
|
240
|
-
testInfoForRequest,
|
|
241
|
-
testFromQueryParams: testFromQueryParams || test,
|
|
242
|
-
});
|
|
168
|
+
let headers = {};
|
|
243
169
|
const queryVariables = variables ? { ...variables } : {};
|
|
244
170
|
if (previewEnabled) {
|
|
245
171
|
queryVariables.version = "CURRENT";
|
|
@@ -247,27 +173,23 @@ export function createPackClient(options) {
|
|
|
247
173
|
else {
|
|
248
174
|
queryVariables.version = "PUBLISHED";
|
|
249
175
|
}
|
|
250
|
-
const testInfoForLoader = getTestInfoForLoader();
|
|
251
176
|
// Preview mode always bypasses the cache
|
|
252
177
|
if (previewEnabled) {
|
|
253
178
|
try {
|
|
254
|
-
return {
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
})),
|
|
259
|
-
packTestInfo: testInfoForLoader,
|
|
260
|
-
};
|
|
179
|
+
return await packClient.fetch(query, {
|
|
180
|
+
variables: queryVariables,
|
|
181
|
+
headers: headers,
|
|
182
|
+
});
|
|
261
183
|
}
|
|
262
184
|
catch (error) {
|
|
263
|
-
return { error
|
|
185
|
+
return { error, data: {} };
|
|
264
186
|
}
|
|
265
187
|
}
|
|
266
188
|
const queryHash = await getCacheKey(withCache, query, token, {
|
|
267
189
|
variables: queryVariables,
|
|
268
190
|
headers,
|
|
269
191
|
});
|
|
270
|
-
|
|
192
|
+
return withCache(queryHash, strategy, async () => {
|
|
271
193
|
try {
|
|
272
194
|
return await packClient.fetch(query, {
|
|
273
195
|
variables: queryVariables,
|
|
@@ -275,13 +197,18 @@ export function createPackClient(options) {
|
|
|
275
197
|
});
|
|
276
198
|
}
|
|
277
199
|
catch (error) {
|
|
278
|
-
return { error, data:
|
|
200
|
+
return { error, data: {} };
|
|
279
201
|
}
|
|
280
202
|
});
|
|
281
|
-
return response.error
|
|
282
|
-
? response
|
|
283
|
-
: { ...response, packTestInfo: testInfoForLoader };
|
|
284
203
|
},
|
|
285
|
-
|
|
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
|
+
},
|
|
286
213
|
};
|
|
287
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,CASnB"}
|
package/dist/handle-request.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { packlytics } from "@pack/packlytics";
|
|
2
2
|
export async function handleRequest(pack, request, handleRequest) {
|
|
3
|
-
const packHandleResponse = await pack.handleRequest(request);
|
|
4
3
|
const response = await packlytics(pack, request, () => {
|
|
5
4
|
return handleRequest(request);
|
|
6
5
|
});
|
|
7
|
-
packHandleResponse(response);
|
|
8
6
|
response.headers.append("powered-by", "Shopify, Hydrogen + Pack Digital");
|
|
9
7
|
response.headers.append("Set-Cookie", await pack.session.commit());
|
|
10
8
|
return response;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { handleRequest } from "./handle-request";
|
|
2
2
|
import { usePackCookies } from "./session/usePackCookies";
|
|
3
3
|
import { PackSession } from "./session/session";
|
|
4
|
-
import {
|
|
4
|
+
import { createPackClient } from "./create-pack-client";
|
|
5
5
|
import { action as previewModeAction, loader as previewModeLoader } from "./preview/preview-mode";
|
|
6
|
-
|
|
7
|
-
export type { Pack };
|
|
8
|
-
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, };
|
|
9
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,
|
|
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, };
|
|
@@ -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;AAInC,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,cAcpB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,MAAM,EAAE,cAqCpB,CAAC"}
|
|
@@ -84,9 +84,7 @@ export const loader = async function ({ request, context }) {
|
|
|
84
84
|
}
|
|
85
85
|
let customizerMetaJson;
|
|
86
86
|
try {
|
|
87
|
-
customizerMetaJson = customizerMeta
|
|
88
|
-
? JSON.parse(customizerMeta)
|
|
89
|
-
: null;
|
|
87
|
+
customizerMetaJson = customizerMeta ? JSON.parse(customizerMeta) : null;
|
|
90
88
|
}
|
|
91
89
|
catch (_error) {
|
|
92
90
|
customizerMetaJson = null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/session/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,OAAO,EACZ,KAAK,cAAc,EACpB,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/session/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,OAAO,EACZ,KAAK,cAAc,EACpB,MAAM,uBAAuB,CAAC;AAI/B,qBAAa,WAAW;;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAOtB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,cAAc,EAC9B,OAAO,EAAE,OAAO;WAQL,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC;IAsB5E,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB,GAAG,CAAC,GAAG,EAAE,MAAM;IAIf,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;IAQ1B,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI;IAIlC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;CAG1B"}
|
package/dist/session/session.js
CHANGED
|
@@ -1,16 +1,6 @@
|
|
|
1
1
|
import { createCookie, createCookieSessionStorage, } from "@shopify/remix-oxygen";
|
|
2
2
|
import { PACK_COOKIE_ID, PACK_COOKIE_MAX_AGE } from "../constants";
|
|
3
3
|
import { buildRandomUUID, hasUserConsent } from "./cookies-utils";
|
|
4
|
-
function isSafari(userAgent) {
|
|
5
|
-
if (!userAgent)
|
|
6
|
-
return false;
|
|
7
|
-
// Check for iOS devices (iPhone/iPad) or macOS Safari
|
|
8
|
-
return (/Safari\//.test(userAgent) &&
|
|
9
|
-
!/Chrome\//.test(userAgent) &&
|
|
10
|
-
!/Chromium\//.test(userAgent) &&
|
|
11
|
-
!/Edg\//.test(userAgent) &&
|
|
12
|
-
!/Firefox\//.test(userAgent));
|
|
13
|
-
}
|
|
14
4
|
export class PackSession {
|
|
15
5
|
id;
|
|
16
6
|
secret;
|
|
@@ -23,12 +13,9 @@ export class PackSession {
|
|
|
23
13
|
this.#sessionStorage = sessionStorage;
|
|
24
14
|
}
|
|
25
15
|
static async init(request, secrets) {
|
|
26
|
-
const userAgent = request.headers.get("User-Agent");
|
|
27
16
|
const storage = createCookieSessionStorage({
|
|
28
17
|
cookie: createCookie(PACK_COOKIE_ID, {
|
|
29
|
-
secure:
|
|
30
|
-
? false
|
|
31
|
-
: true,
|
|
18
|
+
secure: true,
|
|
32
19
|
secrets,
|
|
33
20
|
sameSite: "none",
|
|
34
21
|
maxAge: PACK_COOKIE_MAX_AGE,
|
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.7",
|
|
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.
|
|
25
|
+
"@pack/client": "^1.0.1",
|
|
26
26
|
"@pack/packlytics": "^1.0.1",
|
|
27
|
-
"@shopify/hydrogen": "^2023.10.2"
|
|
28
|
-
"cookie": "^0.6.0",
|
|
29
|
-
"js-cookie": "^3.0.5"
|
|
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, packAbTest } = useRouteLoaderData("root");
|
|
5
|
-
if (abTest === undefined && packAbTest === undefined) {
|
|
6
|
-
throw new Error("ERR_HY_MISSING_AB_TEST_CONTEXT: No A/B test found, are you sure you have call ...pack.getPackContextData() on root loader return? Doc: https://docs.packdigital.com/err/ERR_HY_MISSING_AB_TEST_CONTEXT");
|
|
7
|
-
}
|
|
8
|
-
return abTest || packAbTest;
|
|
9
|
-
}
|
|
10
|
-
export function useAbTestSessionId() {
|
|
11
|
-
// @ts-ignore
|
|
12
|
-
const { sessionId, packSessionId } = useRouteLoaderData("root");
|
|
13
|
-
if (!sessionId && !packSessionId) {
|
|
14
|
-
throw new Error("ERR_HY_MISSING_SESSION_ID: No Session ID found, are you sure you have call ...pack.getPackContextData() on root loader return? Doc: https://docs.packdigital.com/err/ERR_HY_MISSING_SESSION_ID");
|
|
15
|
-
}
|
|
16
|
-
return sessionId || packSessionId;
|
|
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,23 +0,0 @@
|
|
|
1
|
-
import { Dispatch, SetStateAction } from "react";
|
|
2
|
-
export interface Test {
|
|
3
|
-
id: string;
|
|
4
|
-
handle: string;
|
|
5
|
-
testVariant: {
|
|
6
|
-
id: string;
|
|
7
|
-
handle: string;
|
|
8
|
-
};
|
|
9
|
-
}
|
|
10
|
-
interface TestExposureCallbackArg extends Test {
|
|
11
|
-
exposureTime: number;
|
|
12
|
-
}
|
|
13
|
-
type PackTestContextValue = {
|
|
14
|
-
testExposureCallback?: (test: TestExposureCallbackArg) => void;
|
|
15
|
-
hasUserConsent?: boolean | undefined;
|
|
16
|
-
pendingExposureQueue?: Map<any, any>;
|
|
17
|
-
setPendingExposureQueue?: Dispatch<SetStateAction<Map<any, any>>>;
|
|
18
|
-
exposedExperiments?: Set<unknown>;
|
|
19
|
-
};
|
|
20
|
-
export declare const PackTestContext: import("react").Context<PackTestContextValue>;
|
|
21
|
-
export declare const usePackTestContext: () => PackTestContextValue;
|
|
22
|
-
export {};
|
|
23
|
-
//# 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":"AAAA,OAAO,EAA6B,QAAQ,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAE5E,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,UAAU,uBAAwB,SAAQ,IAAI;IAC5C,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,KAAK,oBAAoB,GAAG;IAC1B,oBAAoB,CAAC,EAAE,CAAC,IAAI,EAAE,uBAAuB,KAAK,IAAI,CAAC;IAC/D,cAAc,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,oBAAoB,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACrC,uBAAuB,CAAC,EAAE,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IAClE,kBAAkB,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;CACnC,CAAC;AAEF,eAAO,MAAM,eAAe,+CAA0C,CAAC;AAEvE,eAAO,MAAM,kBAAkB,4BAAoC,CAAC"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import React, { PropsWithChildren } from "react";
|
|
2
|
-
import { Test } from "./pack-test-context";
|
|
3
|
-
interface PackContentProps {
|
|
4
|
-
testExposureCallback?: (test: Test) => void;
|
|
5
|
-
hasUserConsent?: boolean;
|
|
6
|
-
}
|
|
7
|
-
export declare function PackTestProvider({ children, testExposureCallback, hasUserConsent, }: PropsWithChildren<PackContentProps>): React.JSX.Element;
|
|
8
|
-
export {};
|
|
9
|
-
//# 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,EAAY,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAC3D,OAAO,EAAmB,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAE5D,UAAU,gBAAgB;IACxB,oBAAoB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAC5C,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,QAAQ,EACR,oBAAoB,EACpB,cAAsB,GACvB,EAAE,iBAAiB,CAAC,gBAAgB,CAAC,qBAmBrC"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import React, { useState } from "react";
|
|
2
|
-
import { PackTestContext } from "./pack-test-context";
|
|
3
|
-
export function PackTestProvider({ children, testExposureCallback, hasUserConsent = false, }) {
|
|
4
|
-
const [pendingExposureQueue, setPendingExposureQueue] = useState(new Map());
|
|
5
|
-
const [exposedExperiments] = useState(new Set());
|
|
6
|
-
return (React.createElement(PackTestContext.Provider, { value: {
|
|
7
|
-
testExposureCallback: (test) => {
|
|
8
|
-
testExposureCallback && testExposureCallback(test);
|
|
9
|
-
},
|
|
10
|
-
hasUserConsent,
|
|
11
|
-
pendingExposureQueue,
|
|
12
|
-
setPendingExposureQueue,
|
|
13
|
-
exposedExperiments,
|
|
14
|
-
} }, children));
|
|
15
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pack-test-route.d.ts","sourceRoot":"","sources":["../../src/tests/pack-test-route.ts"],"names":[],"mappings":"AA0GA,eAAO,MAAM,aAAa,YAIzB,CAAC"}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { useLoaderData, useMatches } from "@remix-run/react";
|
|
2
|
-
import Cookies from "js-cookie";
|
|
3
|
-
import { useEffect, useState } from "react";
|
|
4
|
-
import { useRevalidator } from "react-router-dom";
|
|
5
|
-
import { usePackTestContext } from "./pack-test-context";
|
|
6
|
-
const usePackLoaderData = () => {
|
|
7
|
-
const [exposedTestInfo, setExposedTestInfo] = useState();
|
|
8
|
-
const { packTestInfo } = useLoaderData();
|
|
9
|
-
const [root] = useMatches();
|
|
10
|
-
const { packIsPreviewMode } = root?.data;
|
|
11
|
-
const { testExposureCallback, hasUserConsent, pendingExposureQueue, setPendingExposureQueue, } = usePackTestContext();
|
|
12
|
-
const revalidator = useRevalidator();
|
|
13
|
-
const exposedTestCookieString = Cookies.get("exposedTest");
|
|
14
|
-
useEffect(() => {
|
|
15
|
-
if (packTestInfo &&
|
|
16
|
-
!packIsPreviewMode &&
|
|
17
|
-
!hasUserConsent &&
|
|
18
|
-
exposedTestCookieString &&
|
|
19
|
-
exposedTestInfo) {
|
|
20
|
-
// Add to the pending exposure queue if no user consent
|
|
21
|
-
setPendingExposureQueue?.((prev) => {
|
|
22
|
-
const newQueue = new Map(prev);
|
|
23
|
-
newQueue.set(packTestInfo.id, {
|
|
24
|
-
packTestInfo,
|
|
25
|
-
exposureTime: Date.now(),
|
|
26
|
-
});
|
|
27
|
-
return newQueue;
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
}, [
|
|
31
|
-
hasUserConsent,
|
|
32
|
-
packTestInfo,
|
|
33
|
-
packIsPreviewMode,
|
|
34
|
-
exposedTestCookieString,
|
|
35
|
-
exposedTestInfo,
|
|
36
|
-
]);
|
|
37
|
-
useEffect(() => {
|
|
38
|
-
if (packTestInfo &&
|
|
39
|
-
hasUserConsent &&
|
|
40
|
-
!exposedTestCookieString &&
|
|
41
|
-
!packIsPreviewMode &&
|
|
42
|
-
!exposedTestInfo) {
|
|
43
|
-
// Set exposedTest cookie used by server to determine if session has been exposed to test
|
|
44
|
-
const expires = new Date();
|
|
45
|
-
expires.setHours(expires.getHours() + 24);
|
|
46
|
-
Cookies.set("exposedTest", JSON.stringify(packTestInfo), {
|
|
47
|
-
expires,
|
|
48
|
-
});
|
|
49
|
-
setExposedTestInfo(packTestInfo);
|
|
50
|
-
console.log("=== TCB HAS USER CONSENT", hasUserConsent);
|
|
51
|
-
// Need to go through current exposure tracking callback queue
|
|
52
|
-
// call tracking callbacks for previous exposures
|
|
53
|
-
pendingExposureQueue?.forEach((data, key) => {
|
|
54
|
-
try {
|
|
55
|
-
testExposureCallback?.({
|
|
56
|
-
...data.packTestInfo,
|
|
57
|
-
exposureTime: data.exposureTime,
|
|
58
|
-
});
|
|
59
|
-
setPendingExposureQueue?.((prev) => {
|
|
60
|
-
const newQueue = new Map(prev);
|
|
61
|
-
newQueue.delete(key);
|
|
62
|
-
return newQueue;
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
catch (error) {
|
|
66
|
-
console.error("Failed to call testExposure after consent:", error);
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
testExposureCallback?.({ ...packTestInfo, exposureTime: Date.now() });
|
|
70
|
-
// TODO: This results in flashing of UI driven by site settings data.
|
|
71
|
-
// Need non-flashing solution.
|
|
72
|
-
revalidator.revalidate();
|
|
73
|
-
}
|
|
74
|
-
}, [packTestInfo, testExposureCallback, exposedTestInfo, hasUserConsent]);
|
|
75
|
-
};
|
|
76
|
-
export const PackTestRoute = () => {
|
|
77
|
-
usePackLoaderData();
|
|
78
|
-
return null;
|
|
79
|
-
};
|
package/dist/tests/test.d.ts
DELETED
|
@@ -1,46 +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
|
-
token: string;
|
|
33
|
-
}
|
|
34
|
-
export interface TestInfo extends Test {
|
|
35
|
-
isFirstExposure?: boolean;
|
|
36
|
-
}
|
|
37
|
-
export declare function getTestInfo({ request, testTargetAudienceAttributes, packClient, session, token, }: GetTestInfoOptions): Promise<TestInfo | undefined>;
|
|
38
|
-
export declare function getTestSession(session: PackSession | undefined, testFromQueryParams: TestInput | null, previewEnabled: boolean): Test | null | undefined;
|
|
39
|
-
export declare function getTestTargetingAttributesFromRequest(request: Request): TestTargetAudienceAttributes;
|
|
40
|
-
export declare function getTestFromQueryParams(request: Request): TestInput | null;
|
|
41
|
-
export declare function setTestHeaders(headers: any, options: {
|
|
42
|
-
previewEnabled: boolean;
|
|
43
|
-
testInfoForRequest?: TestInfo;
|
|
44
|
-
testFromQueryParams?: TestInput;
|
|
45
|
-
}): any;
|
|
46
|
-
//# 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;AAQD,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;IACjC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,QAAS,SAAQ,IAAI;IACpC,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AA2FD,wBAAsB,WAAW,CAAC,EAChC,OAAO,EACP,4BAA4B,EAC5B,UAAU,EACV,OAAO,EACP,KAAK,GACN,EAAE,kBAAkB,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAgGpD;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
DELETED
|
@@ -1,252 +0,0 @@
|
|
|
1
|
-
import cookie from "cookie";
|
|
2
|
-
const QUERY_TEST_VARIANT_IS_RUNNING = `#graphql
|
|
3
|
-
query TestVariantIsRunning($handle: String!, $testId: ID!) {
|
|
4
|
-
testVariantIsRunning(handle: $handle, testId: $testId)
|
|
5
|
-
}
|
|
6
|
-
`;
|
|
7
|
-
async function packClientFetchTestByRules(packClient, testTargetAudienceAttributes, token) {
|
|
8
|
-
if (!packClient.storeId) {
|
|
9
|
-
console.error("Pack error: Store ID is required to fetch a test.");
|
|
10
|
-
return undefined;
|
|
11
|
-
}
|
|
12
|
-
let resp = undefined;
|
|
13
|
-
const URL = "https://tests-service-production.packdigital.workers.dev/tests/assign";
|
|
14
|
-
const assignByRulesResp = await fetch(URL, {
|
|
15
|
-
method: "POST",
|
|
16
|
-
headers: {
|
|
17
|
-
Authorization: `Bearer ${token}`,
|
|
18
|
-
"X-Pack-Storefront-Id": packClient.storeId,
|
|
19
|
-
...(packClient.contentEnvironment
|
|
20
|
-
? { "X-Environment": packClient.contentEnvironment }
|
|
21
|
-
: {}),
|
|
22
|
-
"Content-Type": "application/json",
|
|
23
|
-
},
|
|
24
|
-
body: JSON.stringify({
|
|
25
|
-
attributes: testTargetAudienceAttributes,
|
|
26
|
-
}),
|
|
27
|
-
});
|
|
28
|
-
const { status } = assignByRulesResp;
|
|
29
|
-
if (status !== 200) {
|
|
30
|
-
let message;
|
|
31
|
-
if (status === 401) {
|
|
32
|
-
message =
|
|
33
|
-
"Pack error: Unauthorized request to test assignment service. Please check your token.";
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
message = `Pack error: Request to test assignment service failed with status ${status}`;
|
|
37
|
-
}
|
|
38
|
-
console.error(message);
|
|
39
|
-
return resp;
|
|
40
|
-
}
|
|
41
|
-
const assignByRulesRespJson = await assignByRulesResp.json();
|
|
42
|
-
if (assignByRulesRespJson?.data) {
|
|
43
|
-
resp = {
|
|
44
|
-
...assignByRulesRespJson.data,
|
|
45
|
-
// `isFirstExposure` tells the `<PackTestRoute />` this will be the
|
|
46
|
-
// first exposure on render and will be confirmed next request
|
|
47
|
-
isFirstExposure: true,
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
return resp;
|
|
51
|
-
}
|
|
52
|
-
async function packClientCheckTestIsRunning(packClient, testSession) {
|
|
53
|
-
try {
|
|
54
|
-
const resp = await packClient.fetch(QUERY_TEST_VARIANT_IS_RUNNING, {
|
|
55
|
-
variables: {
|
|
56
|
-
handle: testSession.testVariant.handle,
|
|
57
|
-
testId: testSession.id,
|
|
58
|
-
},
|
|
59
|
-
});
|
|
60
|
-
return !!resp.data.testVariantIsRunning;
|
|
61
|
-
}
|
|
62
|
-
catch (e) {
|
|
63
|
-
console.error(e);
|
|
64
|
-
}
|
|
65
|
-
return false;
|
|
66
|
-
}
|
|
67
|
-
function getExpireAtDate() {
|
|
68
|
-
const expireAt = new Date();
|
|
69
|
-
expireAt.setHours(expireAt.getHours() + 4); // 4 hours
|
|
70
|
-
return expireAt;
|
|
71
|
-
}
|
|
72
|
-
export async function getTestInfo({ request, testTargetAudienceAttributes, packClient, session, token, }) {
|
|
73
|
-
let testInfo = undefined;
|
|
74
|
-
let exposedTest = undefined;
|
|
75
|
-
if (!session) {
|
|
76
|
-
return testInfo;
|
|
77
|
-
}
|
|
78
|
-
const testSession = session.get("test");
|
|
79
|
-
const exposedTestCookieString = cookie.parse(request.headers.get("cookie") || "")?.exposedTest;
|
|
80
|
-
if (exposedTestCookieString) {
|
|
81
|
-
exposedTest = JSON.parse(exposedTestCookieString);
|
|
82
|
-
}
|
|
83
|
-
if (exposedTest && !testSession) {
|
|
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 for the client and store in session
|
|
89
|
-
if (testVariantIsRunning) {
|
|
90
|
-
const { id, handle, testVariant } = exposedTest;
|
|
91
|
-
testInfo = {
|
|
92
|
-
id,
|
|
93
|
-
handle,
|
|
94
|
-
testVariant,
|
|
95
|
-
};
|
|
96
|
-
// Only set the test to the session on exposure
|
|
97
|
-
session.set("test", {
|
|
98
|
-
data: testInfo,
|
|
99
|
-
expireAt: getExpireAtDate(),
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
else {
|
|
103
|
-
// If the test is not running, fetch a new test for the client
|
|
104
|
-
testInfo = await packClientFetchTestByRules(packClient, testTargetAudienceAttributes, token);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
else {
|
|
108
|
-
// If there is no exposed test in the incoming request cookie
|
|
109
|
-
if (testSession && testSession.data?.id && testSession.data?.testVariant) {
|
|
110
|
-
// If there is a test on session, check if the test on session has expired
|
|
111
|
-
if (!testSession.expireAt ||
|
|
112
|
-
new Date(testSession.expireAt) < new Date()) {
|
|
113
|
-
// If there is test on session, check if the test on session is still running
|
|
114
|
-
const testVariantIsRunning = await packClientCheckTestIsRunning(packClient, testSession.data);
|
|
115
|
-
// If true, set testInfo to the testSession assigned test.
|
|
116
|
-
if (testVariantIsRunning) {
|
|
117
|
-
testInfo = testSession.data;
|
|
118
|
-
session.set("test", {
|
|
119
|
-
data: testInfo,
|
|
120
|
-
expireAt: getExpireAtDate(),
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
// If not running, clear test session and fetch a new test for the client
|
|
125
|
-
session.set("test", undefined);
|
|
126
|
-
testInfo = await packClientFetchTestByRules(packClient, testTargetAudienceAttributes, token);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
else {
|
|
130
|
-
testInfo = testSession.data;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
// If there is no test on session and no exposed test, check for a new test for client
|
|
135
|
-
testInfo = await packClientFetchTestByRules(packClient, testTargetAudienceAttributes, token);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
return testInfo;
|
|
139
|
-
}
|
|
140
|
-
export function getTestSession(session, testFromQueryParams, previewEnabled) {
|
|
141
|
-
if (testFromQueryParams) {
|
|
142
|
-
return {
|
|
143
|
-
id: testFromQueryParams.testId || "",
|
|
144
|
-
handle: testFromQueryParams.testHandle || "",
|
|
145
|
-
testVariant: {
|
|
146
|
-
id: testFromQueryParams.testVariantId || "",
|
|
147
|
-
handle: testFromQueryParams.testVariantHandle || "",
|
|
148
|
-
},
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
if (previewEnabled) {
|
|
152
|
-
return {
|
|
153
|
-
id: "",
|
|
154
|
-
handle: "isPreview",
|
|
155
|
-
testVariant: {
|
|
156
|
-
id: "",
|
|
157
|
-
handle: "isPreview",
|
|
158
|
-
},
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
if (!session) {
|
|
162
|
-
return undefined;
|
|
163
|
-
}
|
|
164
|
-
const testSession = session.get("test");
|
|
165
|
-
return testSession?.data || null;
|
|
166
|
-
}
|
|
167
|
-
export function getTestTargetingAttributesFromRequest(request) {
|
|
168
|
-
let testTargetingAttributes = {};
|
|
169
|
-
const requestUrl = new URL(request.url);
|
|
170
|
-
const searchParams = requestUrl.searchParams;
|
|
171
|
-
testTargetingAttributes.url = requestUrl.origin + requestUrl.pathname;
|
|
172
|
-
testTargetingAttributes.query = requestUrl.search;
|
|
173
|
-
testTargetingAttributes.path = requestUrl.pathname;
|
|
174
|
-
searchParams.has("utm_campaign") &&
|
|
175
|
-
(testTargetingAttributes.utmCampaign =
|
|
176
|
-
searchParams.get("utm_campaign") || undefined);
|
|
177
|
-
searchParams.has("utm_content") &&
|
|
178
|
-
(testTargetingAttributes.utmContent =
|
|
179
|
-
searchParams.get("utm_content") || undefined);
|
|
180
|
-
searchParams.has("utm_medium") &&
|
|
181
|
-
(testTargetingAttributes.utmMedium =
|
|
182
|
-
searchParams.get("utm_medium") || undefined);
|
|
183
|
-
searchParams.has("utm_source") &&
|
|
184
|
-
(testTargetingAttributes.utmSource =
|
|
185
|
-
searchParams.get("utm_source") || undefined);
|
|
186
|
-
searchParams.has("utm_term") &&
|
|
187
|
-
(testTargetingAttributes.utmTerm =
|
|
188
|
-
searchParams.get("utm_term") || undefined);
|
|
189
|
-
return testTargetingAttributes;
|
|
190
|
-
}
|
|
191
|
-
export function getTestFromQueryParams(request) {
|
|
192
|
-
const requestUrl = new URL(request.url);
|
|
193
|
-
const params = requestUrl.searchParams;
|
|
194
|
-
if (params.has("testId") ||
|
|
195
|
-
params.has("test_id") ||
|
|
196
|
-
params.has("test-id") ||
|
|
197
|
-
params.has("testHandle") ||
|
|
198
|
-
params.has("test_handle") ||
|
|
199
|
-
params.has("test-handle") ||
|
|
200
|
-
params.has("testVariantId") ||
|
|
201
|
-
params.has("test_variant_id") ||
|
|
202
|
-
params.has("test-variant-id") ||
|
|
203
|
-
params.has("testVariantHandle") ||
|
|
204
|
-
params.has("test_variant_handle") ||
|
|
205
|
-
params.has("test-variant-handle")) {
|
|
206
|
-
return {
|
|
207
|
-
testId: params.get("testId") ||
|
|
208
|
-
params.get("test_id") ||
|
|
209
|
-
params.get("test-id") ||
|
|
210
|
-
"",
|
|
211
|
-
testHandle: params.get("testHandle") ||
|
|
212
|
-
params.get("test_handle") ||
|
|
213
|
-
params.get("test-handle") ||
|
|
214
|
-
"",
|
|
215
|
-
testVariantId: params.get("testVariantId") ||
|
|
216
|
-
params.get("test_variant_id") ||
|
|
217
|
-
params.get("test-variant-id") ||
|
|
218
|
-
"",
|
|
219
|
-
testVariantHandle: params.get("testVariantHandle") ||
|
|
220
|
-
params.get("test_variant_handle") ||
|
|
221
|
-
params.get("test-variant-handle") ||
|
|
222
|
-
"",
|
|
223
|
-
};
|
|
224
|
-
}
|
|
225
|
-
return null;
|
|
226
|
-
}
|
|
227
|
-
export function setTestHeaders(headers, options) {
|
|
228
|
-
const { previewEnabled, testFromQueryParams, testInfoForRequest } = options;
|
|
229
|
-
if (testFromQueryParams) {
|
|
230
|
-
headers["X-Pack-Test-Ignore-Test-Status"] = true;
|
|
231
|
-
if (testFromQueryParams.testId) {
|
|
232
|
-
headers["X-Pack-Test-Id"] = testFromQueryParams.testId;
|
|
233
|
-
}
|
|
234
|
-
if (testFromQueryParams.testHandle) {
|
|
235
|
-
headers["X-Pack-Test-Handle"] = testFromQueryParams.testHandle;
|
|
236
|
-
}
|
|
237
|
-
if (testFromQueryParams.testVariantId) {
|
|
238
|
-
headers["X-Pack-Test-Variant-Id"] = testFromQueryParams.testVariantId;
|
|
239
|
-
}
|
|
240
|
-
if (testFromQueryParams.testVariantHandle) {
|
|
241
|
-
headers["X-Pack-Test-Variant-Handle"] =
|
|
242
|
-
testFromQueryParams.testVariantHandle;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
else if (testInfoForRequest) {
|
|
246
|
-
headers = {
|
|
247
|
-
"X-Pack-Test-Id": testInfoForRequest?.id,
|
|
248
|
-
"X-Pack-Test-Variant-Id": testInfoForRequest?.testVariant?.id,
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
return headers;
|
|
252
|
-
}
|