@reactionary/hcl 0.9.8 → 0.9.11
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/capabilities/cart.capability.js +411 -0
- package/capabilities/category.capability.js +111 -35
- package/capabilities/checkout.capability.js +337 -0
- package/capabilities/identity.capability.js +214 -0
- package/capabilities/inventory.capability.js +75 -0
- package/capabilities/price.capability.js +122 -0
- package/capabilities/product-search.capability.js +64 -13
- package/capabilities/product.capability.js +114 -28
- package/core/client.js +81 -90
- package/core/initialize.js +111 -5
- package/core/session-keys.js +14 -0
- package/factories/cart/cart.factory.js +135 -0
- package/factories/checkout/checkout.factory.js +131 -0
- package/factories/identity/identity.factory.js +12 -0
- package/factories/index.js +5 -0
- package/factories/inventory/inventory.factory.js +38 -0
- package/factories/price/price.factory.js +39 -0
- package/index.js +5 -0
- package/package.json +8 -5
- package/schema/capabilities.schema.js +2 -0
- package/schema/configuration.schema.js +9 -1
- package/src/capabilities/cart.capability.d.ts +69 -0
- package/src/capabilities/category.capability.d.ts +20 -1
- package/src/capabilities/checkout.capability.d.ts +41 -0
- package/src/capabilities/identity.capability.d.ts +29 -0
- package/src/capabilities/inventory.capability.d.ts +13 -0
- package/src/capabilities/price.capability.d.ts +16 -0
- package/src/capabilities/product-search.capability.d.ts +7 -2
- package/src/capabilities/product.capability.d.ts +14 -2
- package/src/core/client.d.ts +41 -14
- package/src/core/initialize.types.d.ts +11 -5
- package/src/core/session-keys.d.ts +14 -0
- package/src/factories/cart/cart.factory.d.ts +11 -0
- package/src/factories/checkout/checkout.factory.d.ts +11 -0
- package/src/factories/identity/identity.factory.d.ts +7 -0
- package/src/factories/index.d.ts +5 -0
- package/src/factories/inventory/inventory.factory.d.ts +29 -0
- package/src/factories/price/price.factory.d.ts +26 -0
- package/src/index.d.ts +5 -0
- package/src/schema/capabilities.schema.d.ts +7 -1
- package/src/schema/configuration.schema.d.ts +6 -0
- package/src/schema/hcl.schema.d.ts +321 -0
- package/src/test/test-utils.d.ts +2 -1
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
4
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
5
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
6
|
+
if (decorator = decorators[i])
|
|
7
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
+
if (kind && result)
|
|
9
|
+
__defProp(target, key, result);
|
|
10
|
+
return result;
|
|
11
|
+
};
|
|
12
|
+
import {
|
|
13
|
+
CustomerPriceQuerySchema,
|
|
14
|
+
ListPriceQuerySchema,
|
|
15
|
+
PriceCapability,
|
|
16
|
+
PriceSchema,
|
|
17
|
+
Reactionary,
|
|
18
|
+
success
|
|
19
|
+
} from "@reactionary/core";
|
|
20
|
+
import { SESSION_KEY_PRICE_RULE_ID } from "../core/session-keys.js";
|
|
21
|
+
class HclPriceCapability extends PriceCapability {
|
|
22
|
+
constructor(cache, context, config, client, factory) {
|
|
23
|
+
super(cache, context);
|
|
24
|
+
this.config = config;
|
|
25
|
+
this.client = client;
|
|
26
|
+
this.factory = factory;
|
|
27
|
+
}
|
|
28
|
+
async getListPrice(payload) {
|
|
29
|
+
const sku = payload.variant.sku;
|
|
30
|
+
const priceRuleId = this.context.session[SESSION_KEY_PRICE_RULE_ID];
|
|
31
|
+
if (!priceRuleId) {
|
|
32
|
+
const response2 = await this.client.callGet(
|
|
33
|
+
this.getCustomerPriceUrl(),
|
|
34
|
+
this.getCustomerPricePayload(sku)
|
|
35
|
+
);
|
|
36
|
+
const rawItem2 = response2.EntitledPrice?.find((i) => i.partNumber === sku);
|
|
37
|
+
if (!rawItem2) {
|
|
38
|
+
return success(
|
|
39
|
+
this.factory.parsePrice(this.context, {
|
|
40
|
+
item: { partNumber: sku }
|
|
41
|
+
})
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
return success(
|
|
45
|
+
this.factory.parsePrice(this.context, {
|
|
46
|
+
item: rawItem2
|
|
47
|
+
})
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
const response = await this.client.callGet(
|
|
51
|
+
this.getListPriceUrl(),
|
|
52
|
+
this.getListPricePayload(sku, priceRuleId)
|
|
53
|
+
);
|
|
54
|
+
const rawItem = response.resultList?.find((i) => i.partNumber === sku);
|
|
55
|
+
if (!rawItem) {
|
|
56
|
+
return success(
|
|
57
|
+
this.factory.parsePrice(this.context, {
|
|
58
|
+
item: { partNumber: sku }
|
|
59
|
+
})
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
return success(
|
|
63
|
+
this.factory.parsePrice(this.context, {
|
|
64
|
+
item: rawItem
|
|
65
|
+
})
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
async getCustomerPrice(payload) {
|
|
69
|
+
const sku = payload.variant.sku;
|
|
70
|
+
const response = await this.client.callGet(
|
|
71
|
+
this.getCustomerPriceUrl(),
|
|
72
|
+
this.getCustomerPricePayload(sku)
|
|
73
|
+
);
|
|
74
|
+
const rawItem = response.EntitledPrice?.find((i) => i.partNumber === sku);
|
|
75
|
+
if (!rawItem) {
|
|
76
|
+
return success(
|
|
77
|
+
this.factory.parsePrice(this.context, {
|
|
78
|
+
item: { partNumber: sku }
|
|
79
|
+
})
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
return success(
|
|
83
|
+
this.factory.parsePrice(this.context, {
|
|
84
|
+
item: rawItem
|
|
85
|
+
})
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
getListPriceUrl() {
|
|
89
|
+
return `${this.client.transactionBaseUrl}/display_price`;
|
|
90
|
+
}
|
|
91
|
+
getListPricePayload(sku, priceRuleId) {
|
|
92
|
+
const params = new URLSearchParams();
|
|
93
|
+
params.set("q", "byPartNumbersAndPriceRuleId");
|
|
94
|
+
params.set("priceRuleId", priceRuleId);
|
|
95
|
+
params.append("partNumber", sku);
|
|
96
|
+
return params;
|
|
97
|
+
}
|
|
98
|
+
getCustomerPriceUrl() {
|
|
99
|
+
return `${this.client.transactionBaseUrl}/price`;
|
|
100
|
+
}
|
|
101
|
+
getCustomerPricePayload(sku) {
|
|
102
|
+
const params = new URLSearchParams();
|
|
103
|
+
params.set("q", "byPartNumbers");
|
|
104
|
+
params.append("partNumber", sku);
|
|
105
|
+
return params;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
__decorateClass([
|
|
109
|
+
Reactionary({
|
|
110
|
+
inputSchema: ListPriceQuerySchema,
|
|
111
|
+
outputSchema: PriceSchema
|
|
112
|
+
})
|
|
113
|
+
], HclPriceCapability.prototype, "getListPrice", 1);
|
|
114
|
+
__decorateClass([
|
|
115
|
+
Reactionary({
|
|
116
|
+
inputSchema: CustomerPriceQuerySchema,
|
|
117
|
+
outputSchema: PriceSchema
|
|
118
|
+
})
|
|
119
|
+
], HclPriceCapability.prototype, "getCustomerPrice", 1);
|
|
120
|
+
export {
|
|
121
|
+
HclPriceCapability
|
|
122
|
+
};
|
|
@@ -18,7 +18,6 @@ import {
|
|
|
18
18
|
Reactionary,
|
|
19
19
|
success
|
|
20
20
|
} from "@reactionary/core";
|
|
21
|
-
import { getLocaleParams } from "../core/locale-params.js";
|
|
22
21
|
class HclProductSearchCapability extends ProductSearchCapability {
|
|
23
22
|
constructor(cache, context, config, client, factory) {
|
|
24
23
|
super(cache, context);
|
|
@@ -29,21 +28,19 @@ class HclProductSearchCapability extends ProductSearchCapability {
|
|
|
29
28
|
queryByTermPayload(payload) {
|
|
30
29
|
const { term, paginationOptions, categoryFilter, facets } = payload.search;
|
|
31
30
|
const { pageNumber, pageSize } = paginationOptions;
|
|
32
|
-
const { langId, currency } = getLocaleParams(this.config, this.context);
|
|
33
31
|
const categoryId = categoryFilter?.key || void 0;
|
|
34
|
-
return {
|
|
32
|
+
return this.productsParams({
|
|
35
33
|
searchTerm: term || void 0,
|
|
36
34
|
categoryId,
|
|
37
35
|
limit: pageSize,
|
|
38
36
|
offset: (pageNumber - 1) * pageSize,
|
|
39
37
|
profileName: categoryId ? this.config.profiles.categoryBrowse : this.config.profiles.productSearch,
|
|
40
|
-
facets: facets.length > 0 ? facets.map((f) => f.key) : void 0
|
|
41
|
-
|
|
42
|
-
currency
|
|
43
|
-
};
|
|
38
|
+
facets: facets.length > 0 ? facets.map((f) => f.key) : void 0
|
|
39
|
+
});
|
|
44
40
|
}
|
|
45
41
|
async queryByTerm(payload) {
|
|
46
|
-
const response = await this.client.
|
|
42
|
+
const response = await this.client.callGet(
|
|
43
|
+
this.queryByTermUrl(payload),
|
|
47
44
|
this.queryByTermPayload(payload)
|
|
48
45
|
);
|
|
49
46
|
const value = this.factory.parseSearchResult(
|
|
@@ -58,11 +55,10 @@ class HclProductSearchCapability extends ProductSearchCapability {
|
|
|
58
55
|
const externalKey = leaf?.identifier.key ?? "";
|
|
59
56
|
let uniqueId = leaf?.uniqueId;
|
|
60
57
|
if (!uniqueId) {
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
identifier: [externalKey]
|
|
64
|
-
|
|
65
|
-
});
|
|
58
|
+
const catResp = await this.client.callGet(
|
|
59
|
+
this.categoriesUrl(),
|
|
60
|
+
this.categoriesParams({ identifier: [externalKey] })
|
|
61
|
+
);
|
|
66
62
|
uniqueId = catResp.contents?.[0]?.uniqueID ?? externalKey;
|
|
67
63
|
}
|
|
68
64
|
const filter = {
|
|
@@ -71,6 +67,61 @@ class HclProductSearchCapability extends ProductSearchCapability {
|
|
|
71
67
|
};
|
|
72
68
|
return success(filter);
|
|
73
69
|
}
|
|
70
|
+
queryByTermUrl(_payload) {
|
|
71
|
+
return this.productsUrl();
|
|
72
|
+
}
|
|
73
|
+
productsUrl() {
|
|
74
|
+
return `${this.client.catalogBaseUrl}/api/v2/products`;
|
|
75
|
+
}
|
|
76
|
+
productsParams(query) {
|
|
77
|
+
const params = new URLSearchParams();
|
|
78
|
+
params.set("storeId", query.storeId ?? this.config.storeId);
|
|
79
|
+
const catalogId = query.catalogId ?? this.config.catalogId;
|
|
80
|
+
if (catalogId)
|
|
81
|
+
params.set("catalogId", catalogId);
|
|
82
|
+
if (query.categoryId)
|
|
83
|
+
params.set("categoryId", query.categoryId);
|
|
84
|
+
if (query.searchTerm)
|
|
85
|
+
params.set("searchTerm", query.searchTerm);
|
|
86
|
+
if (query.contractId)
|
|
87
|
+
params.set("contractId", query.contractId);
|
|
88
|
+
if (query.profileName)
|
|
89
|
+
params.set("profileName", query.profileName);
|
|
90
|
+
if (query.limit !== void 0)
|
|
91
|
+
params.set("limit", String(query.limit));
|
|
92
|
+
if (query.offset !== void 0)
|
|
93
|
+
params.set("offset", String(query.offset));
|
|
94
|
+
if (query.checkEntitlement !== void 0)
|
|
95
|
+
params.set("checkEntitlement", String(query.checkEntitlement));
|
|
96
|
+
for (const id of query.id ?? [])
|
|
97
|
+
params.append("id", id);
|
|
98
|
+
for (const pn of query.partNumber ?? [])
|
|
99
|
+
params.append("partNumber", pn);
|
|
100
|
+
for (const facet of query.facets ?? [])
|
|
101
|
+
params.append("facet", facet);
|
|
102
|
+
return params;
|
|
103
|
+
}
|
|
104
|
+
categoriesUrl() {
|
|
105
|
+
return `${this.client.catalogBaseUrl}/api/v2/categories`;
|
|
106
|
+
}
|
|
107
|
+
categoriesParams(query) {
|
|
108
|
+
const params = new URLSearchParams();
|
|
109
|
+
params.set("storeId", query.storeId ?? this.config.storeId);
|
|
110
|
+
const catalogId = query.catalogId ?? this.config.catalogId;
|
|
111
|
+
if (catalogId)
|
|
112
|
+
params.set("catalogId", catalogId);
|
|
113
|
+
if (query.parentCategoryId)
|
|
114
|
+
params.set("parentCategoryId", query.parentCategoryId);
|
|
115
|
+
if (query.depthAndLimit)
|
|
116
|
+
params.set("depthAndLimit", query.depthAndLimit);
|
|
117
|
+
if (query.profileName)
|
|
118
|
+
params.set("profileName", query.profileName);
|
|
119
|
+
for (const id of query.id ?? [])
|
|
120
|
+
params.append("id", id);
|
|
121
|
+
for (const identifier of query.identifier ?? [])
|
|
122
|
+
params.append("identifier", identifier);
|
|
123
|
+
return params;
|
|
124
|
+
}
|
|
74
125
|
}
|
|
75
126
|
__decorateClass([
|
|
76
127
|
Reactionary({
|
|
@@ -19,7 +19,6 @@ import {
|
|
|
19
19
|
error,
|
|
20
20
|
success
|
|
21
21
|
} from "@reactionary/core";
|
|
22
|
-
import { getLocaleParams } from "../core/locale-params.js";
|
|
23
22
|
class HclProductCapability extends ProductCapability {
|
|
24
23
|
constructor(cache, context, config, client, factory) {
|
|
25
24
|
super(cache, context);
|
|
@@ -28,13 +27,10 @@ class HclProductCapability extends ProductCapability {
|
|
|
28
27
|
this.factory = factory;
|
|
29
28
|
}
|
|
30
29
|
async getById(payload) {
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
langId,
|
|
36
|
-
currency
|
|
37
|
-
});
|
|
30
|
+
const response = await this.client.callGet(
|
|
31
|
+
this.getByIdUrl(payload),
|
|
32
|
+
this.getByIdPayload(payload)
|
|
33
|
+
);
|
|
38
34
|
const products = response.contents ?? response.catalogEntryView ?? [];
|
|
39
35
|
const data = products[0];
|
|
40
36
|
if (!data) {
|
|
@@ -45,25 +41,27 @@ class HclProductCapability extends ProductCapability {
|
|
|
45
41
|
}
|
|
46
42
|
const value = this.factory.parseProduct(
|
|
47
43
|
this.context,
|
|
48
|
-
await this.withResolvedParentCategories(data
|
|
44
|
+
await this.withResolvedParentCategories(data)
|
|
49
45
|
);
|
|
50
46
|
return success(value);
|
|
51
47
|
}
|
|
52
48
|
async getBySlug(payload) {
|
|
53
|
-
const
|
|
54
|
-
|
|
49
|
+
const urlResponse = await this.client.callGet(
|
|
50
|
+
this.urlsUrl(),
|
|
51
|
+
this.urlsParams(payload.slug),
|
|
52
|
+
{ allowUndefined: true }
|
|
53
|
+
);
|
|
54
|
+
const token = urlResponse?.contents?.[0];
|
|
55
55
|
if (!token || token.tokenName !== "ProductToken" || !token.tokenExternalValue) {
|
|
56
56
|
return error({
|
|
57
57
|
type: "NotFound",
|
|
58
58
|
identifier: payload.slug
|
|
59
59
|
});
|
|
60
60
|
}
|
|
61
|
-
const response = await this.client.
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
currency
|
|
66
|
-
});
|
|
61
|
+
const response = await this.client.callGet(
|
|
62
|
+
this.getBySlugUrl(token),
|
|
63
|
+
this.getBySlugPayload(token)
|
|
64
|
+
);
|
|
67
65
|
const products = response.contents ?? response.catalogEntryView ?? [];
|
|
68
66
|
const data = products[0];
|
|
69
67
|
if (!data) {
|
|
@@ -74,18 +72,15 @@ class HclProductCapability extends ProductCapability {
|
|
|
74
72
|
}
|
|
75
73
|
const value = this.factory.parseProduct(
|
|
76
74
|
this.context,
|
|
77
|
-
await this.withResolvedParentCategories(data
|
|
75
|
+
await this.withResolvedParentCategories(data)
|
|
78
76
|
);
|
|
79
77
|
return success(value);
|
|
80
78
|
}
|
|
81
79
|
async getBySKU(payload) {
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
langId,
|
|
87
|
-
currency
|
|
88
|
-
});
|
|
80
|
+
const response = await this.client.callGet(
|
|
81
|
+
this.getBySKUUrl(payload),
|
|
82
|
+
this.getBySKUPayload(payload)
|
|
83
|
+
);
|
|
89
84
|
const products = response.contents ?? response.catalogEntryView ?? [];
|
|
90
85
|
const data = products[0];
|
|
91
86
|
if (!data) {
|
|
@@ -96,7 +91,7 @@ class HclProductCapability extends ProductCapability {
|
|
|
96
91
|
}
|
|
97
92
|
const value = this.factory.parseProduct(
|
|
98
93
|
this.context,
|
|
99
|
-
await this.withResolvedParentCategories(data
|
|
94
|
+
await this.withResolvedParentCategories(data)
|
|
100
95
|
);
|
|
101
96
|
return success(value);
|
|
102
97
|
}
|
|
@@ -105,7 +100,7 @@ class HclProductCapability extends ProductCapability {
|
|
|
105
100
|
* category identifiers (e.g. "LivingRoomFurniture") so the factory receives
|
|
106
101
|
* human-readable keys rather than internal uniqueIDs.
|
|
107
102
|
*/
|
|
108
|
-
async withResolvedParentCategories(data
|
|
103
|
+
async withResolvedParentCategories(data) {
|
|
109
104
|
const rawIds = Array.isArray(data.parentCatalogGroupID) ? data.parentCatalogGroupID : data.parentCatalogGroupID ? [data.parentCatalogGroupID] : [];
|
|
110
105
|
const uniqueIds = [
|
|
111
106
|
...new Set(
|
|
@@ -114,13 +109,104 @@ class HclProductCapability extends ProductCapability {
|
|
|
114
109
|
];
|
|
115
110
|
if (uniqueIds.length === 0)
|
|
116
111
|
return data;
|
|
117
|
-
const catResp = await this.client.
|
|
112
|
+
const catResp = await this.client.callGet(
|
|
113
|
+
this.categoriesUrl(),
|
|
114
|
+
this.categoriesParams({ id: uniqueIds })
|
|
115
|
+
);
|
|
118
116
|
const idToIdentifier = new Map(
|
|
119
117
|
(catResp.contents ?? []).map((c) => [c.uniqueID, c.identifier])
|
|
120
118
|
);
|
|
121
119
|
const resolvedIds = uniqueIds.map((id) => idToIdentifier.get(id) ?? id);
|
|
122
120
|
return { ...data, parentCatalogGroupID: resolvedIds };
|
|
123
121
|
}
|
|
122
|
+
getByIdUrl(_payload) {
|
|
123
|
+
return this.productsUrl();
|
|
124
|
+
}
|
|
125
|
+
getBySlugUrl(_token) {
|
|
126
|
+
return this.productsUrl();
|
|
127
|
+
}
|
|
128
|
+
getBySKUUrl(_payload) {
|
|
129
|
+
return this.productsUrl();
|
|
130
|
+
}
|
|
131
|
+
getByIdPayload(payload) {
|
|
132
|
+
return this.productsParams({
|
|
133
|
+
partNumber: [payload.identifier.key],
|
|
134
|
+
profileName: this.config.profiles.product
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
getBySlugPayload(token) {
|
|
138
|
+
return this.productsParams({
|
|
139
|
+
partNumber: [token.tokenExternalValue],
|
|
140
|
+
profileName: this.config.profiles.product
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
getBySKUPayload(payload) {
|
|
144
|
+
return this.productsParams({
|
|
145
|
+
partNumber: [payload.variant.sku],
|
|
146
|
+
profileName: this.config.profiles.product
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
productsUrl() {
|
|
150
|
+
return `${this.client.catalogBaseUrl}/api/v2/products`;
|
|
151
|
+
}
|
|
152
|
+
productsParams(query) {
|
|
153
|
+
const params = new URLSearchParams();
|
|
154
|
+
params.set("storeId", query.storeId ?? this.config.storeId);
|
|
155
|
+
const catalogId = query.catalogId ?? this.config.catalogId;
|
|
156
|
+
if (catalogId)
|
|
157
|
+
params.set("catalogId", catalogId);
|
|
158
|
+
if (query.categoryId)
|
|
159
|
+
params.set("categoryId", query.categoryId);
|
|
160
|
+
if (query.searchTerm)
|
|
161
|
+
params.set("searchTerm", query.searchTerm);
|
|
162
|
+
if (query.contractId)
|
|
163
|
+
params.set("contractId", query.contractId);
|
|
164
|
+
if (query.profileName)
|
|
165
|
+
params.set("profileName", query.profileName);
|
|
166
|
+
if (query.limit !== void 0)
|
|
167
|
+
params.set("limit", String(query.limit));
|
|
168
|
+
if (query.offset !== void 0)
|
|
169
|
+
params.set("offset", String(query.offset));
|
|
170
|
+
if (query.checkEntitlement !== void 0)
|
|
171
|
+
params.set("checkEntitlement", String(query.checkEntitlement));
|
|
172
|
+
for (const id of query.id ?? [])
|
|
173
|
+
params.append("id", id);
|
|
174
|
+
for (const pn of query.partNumber ?? [])
|
|
175
|
+
params.append("partNumber", pn);
|
|
176
|
+
for (const facet of query.facets ?? [])
|
|
177
|
+
params.append("facet", facet);
|
|
178
|
+
return params;
|
|
179
|
+
}
|
|
180
|
+
categoriesUrl() {
|
|
181
|
+
return `${this.client.catalogBaseUrl}/api/v2/categories`;
|
|
182
|
+
}
|
|
183
|
+
categoriesParams(query) {
|
|
184
|
+
const params = new URLSearchParams();
|
|
185
|
+
params.set("storeId", query.storeId ?? this.config.storeId);
|
|
186
|
+
const catalogId = query.catalogId ?? this.config.catalogId;
|
|
187
|
+
if (catalogId)
|
|
188
|
+
params.set("catalogId", catalogId);
|
|
189
|
+
if (query.parentCategoryId)
|
|
190
|
+
params.set("parentCategoryId", query.parentCategoryId);
|
|
191
|
+
if (query.depthAndLimit)
|
|
192
|
+
params.set("depthAndLimit", query.depthAndLimit);
|
|
193
|
+
if (query.profileName)
|
|
194
|
+
params.set("profileName", query.profileName);
|
|
195
|
+
for (const id of query.id ?? [])
|
|
196
|
+
params.append("id", id);
|
|
197
|
+
for (const identifier of query.identifier ?? [])
|
|
198
|
+
params.append("identifier", identifier);
|
|
199
|
+
return params;
|
|
200
|
+
}
|
|
201
|
+
urlsUrl() {
|
|
202
|
+
return `${this.client.catalogBaseUrl}/api/v2/urls`;
|
|
203
|
+
}
|
|
204
|
+
urlsParams(slug) {
|
|
205
|
+
const params = new URLSearchParams();
|
|
206
|
+
params.set("storeId", this.config.storeId);
|
|
207
|
+
params.append("identifier", slug);
|
|
208
|
+
return params;
|
|
209
|
+
}
|
|
124
210
|
}
|
|
125
211
|
__decorateClass([
|
|
126
212
|
Reactionary({
|
package/core/client.js
CHANGED
|
@@ -1,120 +1,111 @@
|
|
|
1
|
+
import { getLocaleParams } from "./locale-params.js";
|
|
2
|
+
import {
|
|
3
|
+
SESSION_KEY_PERSONALIZATION_ID,
|
|
4
|
+
SESSION_KEY_WC_TOKEN,
|
|
5
|
+
SESSION_KEY_WC_TRUSTED_TOKEN
|
|
6
|
+
} from "./session-keys.js";
|
|
7
|
+
class HclCartNotFoundError extends Error {
|
|
8
|
+
constructor() {
|
|
9
|
+
super("No active cart found");
|
|
10
|
+
this.name = "HclCartNotFoundError";
|
|
11
|
+
}
|
|
12
|
+
}
|
|
1
13
|
class HclClient {
|
|
2
|
-
constructor(config) {
|
|
14
|
+
constructor(config, context) {
|
|
3
15
|
this.config = config;
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
|
|
16
|
+
this.context = context;
|
|
17
|
+
const origin = config.apiUrl.replace(/\/+$/, "");
|
|
18
|
+
const searchOrigin = (config.searchApiUrl ?? config.apiUrl).replace(/\/+$/, "");
|
|
19
|
+
this.catalogBaseUrl = `${searchOrigin}/search/resources`;
|
|
20
|
+
this.transactionBaseUrl = `${origin}/wcs/resources/store/${config.storeId}`;
|
|
7
21
|
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
params.set("langId", query.langId);
|
|
17
|
-
if (query.currency)
|
|
18
|
-
params.set("currency", query.currency);
|
|
19
|
-
if (query.categoryId)
|
|
20
|
-
params.set("categoryId", query.categoryId);
|
|
21
|
-
if (query.searchTerm)
|
|
22
|
-
params.set("searchTerm", query.searchTerm);
|
|
23
|
-
if (query.contractId)
|
|
24
|
-
params.set("contractId", query.contractId);
|
|
25
|
-
if (query.profileName)
|
|
26
|
-
params.set("profileName", query.profileName);
|
|
27
|
-
if (query.limit !== void 0)
|
|
28
|
-
params.set("limit", String(query.limit));
|
|
29
|
-
if (query.offset !== void 0)
|
|
30
|
-
params.set("offset", String(query.offset));
|
|
31
|
-
if (query.checkEntitlement !== void 0) {
|
|
32
|
-
params.set("checkEntitlement", String(query.checkEntitlement));
|
|
33
|
-
}
|
|
34
|
-
for (const id of query.id ?? []) {
|
|
35
|
-
params.append("id", id);
|
|
36
|
-
}
|
|
37
|
-
for (const partNumber of query.partNumber ?? []) {
|
|
38
|
-
params.append("partNumber", partNumber);
|
|
39
|
-
}
|
|
40
|
-
for (const facet of query.facets ?? []) {
|
|
41
|
-
params.append("facet", facet);
|
|
42
|
-
}
|
|
43
|
-
const url = `${this.baseUrl}/products?${params.toString()}`;
|
|
44
|
-
const response = await fetch(url, {
|
|
22
|
+
/** Base URL for the Query Service (catalog / search). */
|
|
23
|
+
catalogBaseUrl;
|
|
24
|
+
/** Base URL for the Transaction Service (WCS REST). */
|
|
25
|
+
transactionBaseUrl;
|
|
26
|
+
async callGet(url, params, opts) {
|
|
27
|
+
const merged = this.buildParams(params);
|
|
28
|
+
const query = merged.toString() ? `?${merged.toString()}` : "";
|
|
29
|
+
const response = await fetch(`${url}${query}`, {
|
|
45
30
|
method: "GET",
|
|
46
|
-
headers:
|
|
31
|
+
headers: this.buildHeaders()
|
|
47
32
|
});
|
|
33
|
+
if (opts?.allowUndefined && response.status === 404)
|
|
34
|
+
return void 0;
|
|
48
35
|
if (!response.ok) {
|
|
49
36
|
throw new Error(
|
|
50
|
-
`HCL
|
|
37
|
+
`HCL GET ${url} error ${response.status} ${response.statusText}`
|
|
51
38
|
);
|
|
52
39
|
}
|
|
53
40
|
return response.json();
|
|
54
41
|
}
|
|
55
|
-
|
|
56
|
-
* Resolve a URL slug to an HCL token (product partNumber, category ID, etc.).
|
|
57
|
-
* Calls GET /api/v2/urls?storeId=X&identifier=<slug>
|
|
58
|
-
* Returns undefined when the slug is not found (404).
|
|
59
|
-
*/
|
|
60
|
-
async resolveSlug(slug, langId) {
|
|
61
|
-
const params = new URLSearchParams();
|
|
62
|
-
params.set("storeId", this.config.storeId);
|
|
63
|
-
params.append("identifier", slug);
|
|
64
|
-
if (langId)
|
|
65
|
-
params.set("langId", langId);
|
|
66
|
-
const url = `${this.baseUrl}/urls?${params.toString()}`;
|
|
42
|
+
async callPost(url, body = {}) {
|
|
67
43
|
const response = await fetch(url, {
|
|
68
|
-
method: "
|
|
69
|
-
headers: {
|
|
44
|
+
method: "POST",
|
|
45
|
+
headers: { ...this.buildHeaders(), "Content-Type": "application/json" },
|
|
46
|
+
body: JSON.stringify(body)
|
|
70
47
|
});
|
|
71
|
-
if (response.status === 404)
|
|
72
|
-
return void 0;
|
|
73
48
|
if (!response.ok) {
|
|
49
|
+
const text = await response.text();
|
|
74
50
|
throw new Error(
|
|
75
|
-
`HCL
|
|
51
|
+
`HCL POST ${url} error ${response.status} ${response.statusText}: ${text}`
|
|
76
52
|
);
|
|
77
53
|
}
|
|
78
|
-
|
|
79
|
-
return data.contents?.[0];
|
|
54
|
+
return response.json();
|
|
80
55
|
}
|
|
81
|
-
|
|
82
|
-
* Query categories from the HCL Commerce Query Service.
|
|
83
|
-
* Calls GET /api/v2/categories with the given query parameters.
|
|
84
|
-
*/
|
|
85
|
-
async findCategories(query) {
|
|
86
|
-
const params = new URLSearchParams();
|
|
87
|
-
params.set("storeId", query.storeId ?? this.config.storeId);
|
|
88
|
-
const catalogId = query.catalogId ?? this.config.catalogId;
|
|
89
|
-
if (catalogId)
|
|
90
|
-
params.set("catalogId", catalogId);
|
|
91
|
-
if (query.langId)
|
|
92
|
-
params.set("langId", query.langId);
|
|
93
|
-
if (query.parentCategoryId)
|
|
94
|
-
params.set("parentCategoryId", query.parentCategoryId);
|
|
95
|
-
if (query.depthAndLimit)
|
|
96
|
-
params.set("depthAndLimit", query.depthAndLimit);
|
|
97
|
-
if (query.profileName)
|
|
98
|
-
params.set("profileName", query.profileName);
|
|
99
|
-
for (const id of query.id ?? []) {
|
|
100
|
-
params.append("id", id);
|
|
101
|
-
}
|
|
102
|
-
for (const identifier of query.identifier ?? []) {
|
|
103
|
-
params.append("identifier", identifier);
|
|
104
|
-
}
|
|
105
|
-
const url = `${this.baseUrl}/categories?${params.toString()}`;
|
|
56
|
+
async callPut(url, body) {
|
|
106
57
|
const response = await fetch(url, {
|
|
107
|
-
method: "
|
|
108
|
-
headers: {
|
|
58
|
+
method: "PUT",
|
|
59
|
+
headers: { ...this.buildHeaders(), "Content-Type": "application/json" },
|
|
60
|
+
body: JSON.stringify(body)
|
|
109
61
|
});
|
|
110
62
|
if (!response.ok) {
|
|
63
|
+
const text = await response.text();
|
|
111
64
|
throw new Error(
|
|
112
|
-
`HCL
|
|
65
|
+
`HCL PUT ${url} error ${response.status} ${response.statusText}: ${text}`
|
|
113
66
|
);
|
|
114
67
|
}
|
|
115
68
|
return response.json();
|
|
116
69
|
}
|
|
70
|
+
async callDelete(url, opts) {
|
|
71
|
+
const response = await fetch(url, {
|
|
72
|
+
method: "DELETE",
|
|
73
|
+
headers: this.buildHeaders()
|
|
74
|
+
});
|
|
75
|
+
if (!response.ok && !(opts?.ignore404 && response.status === 404)) {
|
|
76
|
+
throw new Error(
|
|
77
|
+
`HCL DELETE ${url} error ${response.status} ${response.statusText}`
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Merges caller-supplied params with locale defaults (langId, currency)
|
|
83
|
+
* derived from the request context. Caller-supplied values always win.
|
|
84
|
+
*/
|
|
85
|
+
buildParams(params) {
|
|
86
|
+
const merged = new URLSearchParams(params);
|
|
87
|
+
const { langId, currency } = getLocaleParams(this.config, this.context);
|
|
88
|
+
if (langId && !merged.has("langId"))
|
|
89
|
+
merged.set("langId", langId);
|
|
90
|
+
if (currency && !merged.has("currency"))
|
|
91
|
+
merged.set("currency", currency);
|
|
92
|
+
return merged;
|
|
93
|
+
}
|
|
94
|
+
buildHeaders() {
|
|
95
|
+
const headers = { Accept: "application/json" };
|
|
96
|
+
const token = this.context.session[SESSION_KEY_WC_TOKEN];
|
|
97
|
+
const trustedToken = this.context.session[SESSION_KEY_WC_TRUSTED_TOKEN];
|
|
98
|
+
const personalizationId = this.context.session[SESSION_KEY_PERSONALIZATION_ID];
|
|
99
|
+
if (token)
|
|
100
|
+
headers["WCToken"] = token;
|
|
101
|
+
if (trustedToken)
|
|
102
|
+
headers["WCTrustedToken"] = trustedToken;
|
|
103
|
+
if (personalizationId)
|
|
104
|
+
headers["WCPersonalization"] = personalizationId;
|
|
105
|
+
return headers;
|
|
106
|
+
}
|
|
117
107
|
}
|
|
118
108
|
export {
|
|
109
|
+
HclCartNotFoundError,
|
|
119
110
|
HclClient
|
|
120
111
|
};
|