@reactionary/hcl 0.9.17 → 0.9.19

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.
@@ -120,16 +120,6 @@ class HclIdentityCapability extends IdentityCapability {
120
120
  }
121
121
  async register(payload) {
122
122
  debug("Registering new user: %s", payload.username);
123
- const guest = await this.client.callPost(
124
- this.createGuestIdentityUrl()
125
- );
126
- this.storeSessionTokens(
127
- guest.WCToken,
128
- guest.WCTrustedToken,
129
- guest.userId,
130
- "guest",
131
- guest.personalizationID
132
- );
133
123
  const registered = await this.client.callPut(
134
124
  this.registerPersonUrl(),
135
125
  this.registerPersonPayload(payload.username, payload.password)
package/core/client.js CHANGED
@@ -1,6 +1,8 @@
1
1
  import { getLocaleParams } from "./locale-params.js";
2
2
  import {
3
+ SESSION_KEY_IDENTITY_TYPE,
3
4
  SESSION_KEY_PERSONALIZATION_ID,
5
+ SESSION_KEY_USER_ID,
4
6
  SESSION_KEY_WC_TOKEN,
5
7
  SESSION_KEY_WC_TRUSTED_TOKEN
6
8
  } from "./session-keys.js";
@@ -15,7 +17,10 @@ class HclClient {
15
17
  this.config = config;
16
18
  this.context = context;
17
19
  const origin = config.apiUrl.replace(/\/+$/, "");
18
- const searchOrigin = (config.searchApiUrl ?? config.apiUrl).replace(/\/+$/, "");
20
+ const searchOrigin = (config.searchApiUrl ?? config.apiUrl).replace(
21
+ /\/+$/,
22
+ ""
23
+ );
19
24
  this.catalogBaseUrl = `${searchOrigin}/search/resources`;
20
25
  this.transactionBaseUrl = `${origin}/wcs/resources/store/${config.storeId}`;
21
26
  }
@@ -40,6 +45,7 @@ class HclClient {
40
45
  return response.json();
41
46
  }
42
47
  async callPost(url, body = {}) {
48
+ await this.ensureGuestSession(url);
43
49
  const response = await fetch(url, {
44
50
  method: "POST",
45
51
  headers: { ...this.buildHeaders(), "Content-Type": "application/json" },
@@ -54,6 +60,7 @@ class HclClient {
54
60
  return response.json();
55
61
  }
56
62
  async callPut(url, body) {
63
+ await this.ensureGuestSession(url);
57
64
  const response = await fetch(url, {
58
65
  method: "PUT",
59
66
  headers: { ...this.buildHeaders(), "Content-Type": "application/json" },
@@ -78,6 +85,67 @@ class HclClient {
78
85
  );
79
86
  }
80
87
  }
88
+ /**
89
+ * Bootstraps a guest WCS session for whitelisted transaction endpoints.
90
+ *
91
+ * Only fires when no WCToken is present AND the URL targets one of the
92
+ * whitelisted capabilities (cart, order, profile). Catalog URLs and
93
+ * non-whitelisted transaction paths are left as anonymous so that browsing
94
+ * sessions never create guest-identity rows in the WCS database.
95
+ *
96
+ * @see requiresGuestSession
97
+ */
98
+ async ensureGuestSession(url) {
99
+ if (!this.requiresGuestSession(url))
100
+ return;
101
+ if (this.context.session[SESSION_KEY_WC_TOKEN])
102
+ return;
103
+ const guestUrl = `${this.transactionBaseUrl}/guestidentity`;
104
+ const response = await fetch(guestUrl, {
105
+ method: "POST",
106
+ headers: {
107
+ "Content-Type": "application/json",
108
+ Accept: "application/json"
109
+ },
110
+ body: JSON.stringify({})
111
+ });
112
+ if (!response.ok) {
113
+ throw new Error(
114
+ `HCL guest identity bootstrap failed: ${response.status} ${response.statusText}`
115
+ );
116
+ }
117
+ const data = await response.json();
118
+ this.context.session[SESSION_KEY_WC_TOKEN] = data.WCToken;
119
+ this.context.session[SESSION_KEY_WC_TRUSTED_TOKEN] = data.WCTrustedToken;
120
+ this.context.session[SESSION_KEY_USER_ID] = data.userId;
121
+ this.context.session[SESSION_KEY_IDENTITY_TYPE] = "guest";
122
+ if (data.personalizationID) {
123
+ this.context.session[SESSION_KEY_PERSONALIZATION_ID] = data.personalizationID;
124
+ } else {
125
+ delete this.context.session[SESSION_KEY_PERSONALIZATION_ID];
126
+ }
127
+ this.context.session.identityContext.identity = {
128
+ type: "Guest",
129
+ id: { userId: data.userId }
130
+ };
131
+ this.context.session.identityContext.lastUpdated = /* @__PURE__ */ new Date();
132
+ }
133
+ /**
134
+ * Returns true when `url` targets a transaction endpoint that should trigger
135
+ * automatic guest-session bootstrapping.
136
+ *
137
+ * Only the following path prefixes are whitelisted — other transaction calls
138
+ * (price rules, espots, segments, inventory, …) must NOT create guest-identity
139
+ * rows in the WCS database for anonymous browsing sessions.
140
+ *
141
+ * Override in project-specific subclasses to adjust the whitelist.
142
+ */
143
+ requiresGuestSession(url) {
144
+ if (!url.startsWith(this.transactionBaseUrl))
145
+ return false;
146
+ const path = url.slice(this.transactionBaseUrl.length);
147
+ return path.startsWith("/cart") || path.startsWith("/order") || path.startsWith("/person");
148
+ }
81
149
  /**
82
150
  * Merges caller-supplied params with locale defaults (langId, currency)
83
151
  * derived from the request context. Caller-supplied values always win.
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@reactionary/hcl",
3
- "version": "0.9.17",
3
+ "version": "0.9.19",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "types": "./src/index.d.ts",
7
7
  "dependencies": {
8
- "@reactionary/core": "0.9.17",
8
+ "@reactionary/core": "0.9.19",
9
9
  "debug": "^4.4.3",
10
10
  "zod": "4.1.9"
11
11
  },
@@ -37,6 +37,28 @@ export declare class HclClient {
37
37
  callDelete(url: string, opts?: {
38
38
  ignore404?: boolean;
39
39
  }): Promise<void>;
40
+ /**
41
+ * Bootstraps a guest WCS session for whitelisted transaction endpoints.
42
+ *
43
+ * Only fires when no WCToken is present AND the URL targets one of the
44
+ * whitelisted capabilities (cart, order, profile). Catalog URLs and
45
+ * non-whitelisted transaction paths are left as anonymous so that browsing
46
+ * sessions never create guest-identity rows in the WCS database.
47
+ *
48
+ * @see requiresGuestSession
49
+ */
50
+ protected ensureGuestSession(url: string): Promise<void>;
51
+ /**
52
+ * Returns true when `url` targets a transaction endpoint that should trigger
53
+ * automatic guest-session bootstrapping.
54
+ *
55
+ * Only the following path prefixes are whitelisted — other transaction calls
56
+ * (price rules, espots, segments, inventory, …) must NOT create guest-identity
57
+ * rows in the WCS database for anonymous browsing sessions.
58
+ *
59
+ * Override in project-specific subclasses to adjust the whitelist.
60
+ */
61
+ protected requiresGuestSession(url: string): boolean;
40
62
  /**
41
63
  * Merges caller-supplied params with locale defaults (langId, currency)
42
64
  * derived from the request context. Caller-supplied values always win.