@reactionary/hcl 0.9.12 → 0.9.14
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/analytics.capability.js +98 -0
- package/capabilities/company.capability.js +307 -0
- package/capabilities/personalization-profile.capability.js +85 -0
- package/capabilities/product-associations.capability.js +117 -0
- package/capabilities/product-list.capability.js +665 -0
- package/capabilities/product-recommendations.capability.js +143 -0
- package/capabilities/store.capability.js +72 -0
- package/core/initialize.js +148 -2
- package/factories/company/company.factory.js +77 -0
- package/factories/index.js +6 -0
- package/factories/personalization-profile/personalization-profile.factory.js +16 -0
- package/factories/product-associations/product-associations.factory.js +16 -0
- package/factories/product-list/product-list.factory.js +158 -0
- package/factories/product-recommendations/product-recommendations.factory.js +17 -0
- package/factories/store/store.factory.js +18 -0
- package/index.js +7 -0
- package/package.json +2 -2
- package/schema/capabilities.schema.js +16 -2
- package/schema/configuration.schema.js +37 -1
- package/src/capabilities/analytics.capability.d.ts +17 -0
- package/src/capabilities/company.capability.d.ts +26 -0
- package/src/capabilities/personalization-profile.capability.d.ts +19 -0
- package/src/capabilities/product-associations.capability.d.ts +22 -0
- package/src/capabilities/product-list.capability.d.ts +42 -0
- package/src/capabilities/product-recommendations.capability.d.ts +29 -0
- package/src/capabilities/store.capability.d.ts +13 -0
- package/src/core/initialize.types.d.ts +7 -1
- package/src/factories/company/company.factory.d.ts +11 -0
- package/src/factories/index.d.ts +6 -0
- package/src/factories/personalization-profile/personalization-profile.factory.d.ts +11 -0
- package/src/factories/product-associations/product-associations.factory.d.ts +8 -0
- package/src/factories/product-list/product-list.factory.d.ts +40 -0
- package/src/factories/product-recommendations/product-recommendations.factory.d.ts +12 -0
- package/src/factories/store/store.factory.d.ts +8 -0
- package/src/index.d.ts +7 -0
- package/src/schema/capabilities.schema.d.ts +45 -1
- package/src/schema/configuration.schema.d.ts +24 -0
- package/src/schema/hcl.schema.d.ts +277 -1
- package/src/test/test-utils.d.ts +4 -1
|
@@ -0,0 +1,143 @@
|
|
|
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
|
+
ProductRecommendationsCapability,
|
|
14
|
+
ProductRecommendationsQuerySchema,
|
|
15
|
+
ProductRecommendationsByCollectionQuerySchema,
|
|
16
|
+
Reactionary,
|
|
17
|
+
success
|
|
18
|
+
} from "@reactionary/core";
|
|
19
|
+
class HclProductRecommendationsCapability extends ProductRecommendationsCapability {
|
|
20
|
+
constructor(cache, context, config, client, factory) {
|
|
21
|
+
super(cache, context);
|
|
22
|
+
this.config = config;
|
|
23
|
+
this.client = client;
|
|
24
|
+
this.factory = factory;
|
|
25
|
+
}
|
|
26
|
+
getRecommendations(...args) {
|
|
27
|
+
return super.getRecommendations(...args);
|
|
28
|
+
}
|
|
29
|
+
async getCollection(query) {
|
|
30
|
+
const params = {
|
|
31
|
+
productId: query.sourceProduct?.[0]?.key,
|
|
32
|
+
categoryId: query.sourceCategory?.key,
|
|
33
|
+
count: String(query.numberOfRecommendations)
|
|
34
|
+
};
|
|
35
|
+
const recommendations = await this.fetchEspot(
|
|
36
|
+
query.collectionName,
|
|
37
|
+
query.collectionName,
|
|
38
|
+
params
|
|
39
|
+
);
|
|
40
|
+
return success(recommendations.slice(0, query.numberOfRecommendations));
|
|
41
|
+
}
|
|
42
|
+
async getFrequentlyBoughtTogetherRecommendations(query) {
|
|
43
|
+
return this.fetchEspot(
|
|
44
|
+
this.config.espotNames.frequentlyBoughtTogether,
|
|
45
|
+
"frequentlyBoughtTogether",
|
|
46
|
+
{
|
|
47
|
+
productId: query.sourceProduct.key,
|
|
48
|
+
count: String(query.numberOfRecommendations)
|
|
49
|
+
}
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
async getSimilarProductsRecommendations(query) {
|
|
53
|
+
return this.fetchEspot(this.config.espotNames.similar, "similar", {
|
|
54
|
+
productId: query.sourceProduct.key,
|
|
55
|
+
count: String(query.numberOfRecommendations)
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
async getRelatedProductsRecommendations(query) {
|
|
59
|
+
return this.fetchEspot(this.config.espotNames.related, "related", {
|
|
60
|
+
productId: query.sourceProduct.key,
|
|
61
|
+
count: String(query.numberOfRecommendations)
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
async getTrendingInCategoryRecommendations(query) {
|
|
65
|
+
return this.fetchEspot(
|
|
66
|
+
this.config.espotNames.trendingInCategory,
|
|
67
|
+
"trendingInCategory",
|
|
68
|
+
{
|
|
69
|
+
categoryId: query.sourceCategory.key,
|
|
70
|
+
count: String(query.numberOfRecommendations)
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
async getPopularProductsRecommendations(query) {
|
|
75
|
+
return this.fetchEspot(this.config.espotNames.popular, "popular", {
|
|
76
|
+
count: String(query.numberOfRecommendations)
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
async getTopPicksProductsRecommendations(query) {
|
|
80
|
+
return this.fetchEspot(this.config.espotNames.topPicks, "topPicks", {
|
|
81
|
+
count: String(query.numberOfRecommendations)
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
async getAlsoViewedProductsRecommendations(query) {
|
|
85
|
+
return this.fetchEspot(this.config.espotNames.alsoViewed, "alsoViewed", {
|
|
86
|
+
productId: query.sourceProduct.key,
|
|
87
|
+
count: String(query.numberOfRecommendations)
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Calls an HCL marketing spot (espot) by name and maps its catalog entry
|
|
92
|
+
* activity data to `ProductRecommendation[]` using the factory.
|
|
93
|
+
*
|
|
94
|
+
* Returns an empty array when the espot is not found (404) or returns no
|
|
95
|
+
* catalog entry data — allowing teams to configure only the espots they need.
|
|
96
|
+
*/
|
|
97
|
+
async fetchEspot(name, algorithm, params = {}) {
|
|
98
|
+
const response = await this.client.callGet(
|
|
99
|
+
this.getEspotUrl(name),
|
|
100
|
+
this.getEspotParams(params),
|
|
101
|
+
{ allowUndefined: true }
|
|
102
|
+
);
|
|
103
|
+
if (!response) {
|
|
104
|
+
return [];
|
|
105
|
+
}
|
|
106
|
+
const activities = response.MarketingSpotData?.[0]?.baseMarketingSpotActivityData ?? [];
|
|
107
|
+
return activities.filter(
|
|
108
|
+
(a) => a.baseMarketingSpotDataType === "CatalogEntry" || a.baseMarketingSpotDataType === "CatalogEntryId"
|
|
109
|
+
).map(
|
|
110
|
+
(a) => this.factory.parseRecommendation(this.context, {
|
|
111
|
+
activityData: a,
|
|
112
|
+
algorithm
|
|
113
|
+
})
|
|
114
|
+
).filter((r) => r.product.key !== "");
|
|
115
|
+
}
|
|
116
|
+
getEspotUrl(name) {
|
|
117
|
+
return `${this.client.transactionBaseUrl}/espot/${encodeURIComponent(name)}`;
|
|
118
|
+
}
|
|
119
|
+
getEspotParams(params) {
|
|
120
|
+
const searchParams = new URLSearchParams();
|
|
121
|
+
const count = params["count"];
|
|
122
|
+
if (count)
|
|
123
|
+
searchParams.set("DM_DisplayProducts", count);
|
|
124
|
+
if (params["productId"])
|
|
125
|
+
searchParams.set("productId", params["productId"]);
|
|
126
|
+
if (params["categoryId"])
|
|
127
|
+
searchParams.set("categoryId", params["categoryId"]);
|
|
128
|
+
return searchParams;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
__decorateClass([
|
|
132
|
+
Reactionary({
|
|
133
|
+
inputSchema: ProductRecommendationsQuerySchema
|
|
134
|
+
})
|
|
135
|
+
], HclProductRecommendationsCapability.prototype, "getRecommendations", 1);
|
|
136
|
+
__decorateClass([
|
|
137
|
+
Reactionary({
|
|
138
|
+
inputSchema: ProductRecommendationsByCollectionQuerySchema
|
|
139
|
+
})
|
|
140
|
+
], HclProductRecommendationsCapability.prototype, "getCollection", 1);
|
|
141
|
+
export {
|
|
142
|
+
HclProductRecommendationsCapability
|
|
143
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
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
|
+
Reactionary,
|
|
14
|
+
StoreCapability,
|
|
15
|
+
StoreQueryByProximitySchema,
|
|
16
|
+
StoreSchema,
|
|
17
|
+
success
|
|
18
|
+
} from "@reactionary/core";
|
|
19
|
+
import * as z from "zod";
|
|
20
|
+
import createDebug from "debug";
|
|
21
|
+
const debug = createDebug("reactionary:hcl:store");
|
|
22
|
+
class HclStoreCapability extends StoreCapability {
|
|
23
|
+
config;
|
|
24
|
+
client;
|
|
25
|
+
factory;
|
|
26
|
+
constructor(cache, context, config, client, factory) {
|
|
27
|
+
super(cache, context);
|
|
28
|
+
this.config = config;
|
|
29
|
+
this.client = client;
|
|
30
|
+
this.factory = factory;
|
|
31
|
+
}
|
|
32
|
+
async queryByProximity(payload) {
|
|
33
|
+
debug(
|
|
34
|
+
"queryByProximity lat=%d lon=%d dist=%d",
|
|
35
|
+
payload.latitude,
|
|
36
|
+
payload.longitude,
|
|
37
|
+
payload.distance
|
|
38
|
+
);
|
|
39
|
+
const response = await this.client.callGet(
|
|
40
|
+
this.getStoreLocatorUrl(payload),
|
|
41
|
+
this.getStoreLocatorParams(payload),
|
|
42
|
+
{ allowUndefined: true }
|
|
43
|
+
);
|
|
44
|
+
const stores = (response?.PhysicalStore ?? []).map(
|
|
45
|
+
(store) => this.factory.parseStore(this.context, store)
|
|
46
|
+
);
|
|
47
|
+
return success(stores);
|
|
48
|
+
}
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
// Extension points
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
getStoreLocatorUrl(payload) {
|
|
53
|
+
return `${this.client.transactionBaseUrl}/storelocator/latitude/${payload.latitude}/longitude/${payload.longitude}`;
|
|
54
|
+
}
|
|
55
|
+
getStoreLocatorParams(payload) {
|
|
56
|
+
const params = new URLSearchParams();
|
|
57
|
+
params.set("maxItems", String(payload.limit));
|
|
58
|
+
params.set("radius", String(payload.distance));
|
|
59
|
+
params.set("radiusUOM", "km");
|
|
60
|
+
params.set("siteLevelStoreSearch", "false");
|
|
61
|
+
return params;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
__decorateClass([
|
|
65
|
+
Reactionary({
|
|
66
|
+
inputSchema: StoreQueryByProximitySchema,
|
|
67
|
+
outputSchema: z.array(StoreSchema)
|
|
68
|
+
})
|
|
69
|
+
], HclStoreCapability.prototype, "queryByProximity", 1);
|
|
70
|
+
export {
|
|
71
|
+
HclStoreCapability
|
|
72
|
+
};
|
package/core/initialize.js
CHANGED
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CategoryPaginatedResultSchema,
|
|
3
|
+
CompanyPaginatedListSchema,
|
|
4
|
+
CompanySchema,
|
|
3
5
|
IdentitySchema,
|
|
4
6
|
OrderSchema,
|
|
5
7
|
OrderSearchResultSchema,
|
|
8
|
+
PersonalizationProfileSchema,
|
|
9
|
+
ProductAssociationSchema,
|
|
10
|
+
ProductListItemPaginatedResultsSchema,
|
|
11
|
+
ProductListItemSchema,
|
|
12
|
+
ProductListPaginatedResultsSchema,
|
|
13
|
+
ProductListSchema,
|
|
14
|
+
ProductRecommendationSchema,
|
|
6
15
|
ProductSchema,
|
|
7
|
-
ProfileSchema
|
|
16
|
+
ProfileSchema,
|
|
17
|
+
StoreSchema
|
|
8
18
|
} from "@reactionary/core";
|
|
9
19
|
import { HclCategorySchema } from "../schema/category.schema.js";
|
|
10
20
|
import {
|
|
@@ -21,14 +31,20 @@ import {
|
|
|
21
31
|
HclCartFactory,
|
|
22
32
|
HclCategoryFactory,
|
|
23
33
|
HclCheckoutFactory,
|
|
34
|
+
HclCompanyFactory,
|
|
24
35
|
HclIdentityFactory,
|
|
25
36
|
HclInventoryFactory,
|
|
26
37
|
HclOrderFactory,
|
|
27
38
|
HclOrderSearchFactory,
|
|
39
|
+
HclPersonalizationProfileFactory,
|
|
28
40
|
HclPriceFactory,
|
|
41
|
+
HclProductAssociationsFactory,
|
|
29
42
|
HclProductFactory,
|
|
43
|
+
HclProductListFactory,
|
|
44
|
+
HclProductRecommendationsFactory,
|
|
30
45
|
HclProductSearchFactory,
|
|
31
|
-
HclProfileFactory
|
|
46
|
+
HclProfileFactory,
|
|
47
|
+
HclStoreFactory
|
|
32
48
|
} from "../factories/index.js";
|
|
33
49
|
import { HclCartCapability } from "../capabilities/cart.capability.js";
|
|
34
50
|
import { HclCheckoutCapability } from "../capabilities/checkout.capability.js";
|
|
@@ -41,6 +57,13 @@ import { HclIdentityCapability } from "../capabilities/identity.capability.js";
|
|
|
41
57
|
import { HclProfileCapability } from "../capabilities/profile.capability.js";
|
|
42
58
|
import { HclOrderCapability } from "../capabilities/order.capability.js";
|
|
43
59
|
import { HclOrderSearchCapability } from "../capabilities/order-search.capability.js";
|
|
60
|
+
import { HclAnalyticsCapability } from "../capabilities/analytics.capability.js";
|
|
61
|
+
import { HclProductAssociationsCapability } from "../capabilities/product-associations.capability.js";
|
|
62
|
+
import { HclProductRecommendationsCapability } from "../capabilities/product-recommendations.capability.js";
|
|
63
|
+
import { HclPersonalizationProfileCapability } from "../capabilities/personalization-profile.capability.js";
|
|
64
|
+
import { HclCompanyCapability } from "../capabilities/company.capability.js";
|
|
65
|
+
import { HclStoreCapability } from "../capabilities/store.capability.js";
|
|
66
|
+
import { HclProductListCapability } from "../capabilities/product-list.capability.js";
|
|
44
67
|
import {
|
|
45
68
|
CartIdentifierSchema,
|
|
46
69
|
CartPaginatedSearchResultSchema,
|
|
@@ -252,6 +275,129 @@ function withHclCapabilities(configuration, capabilities) {
|
|
|
252
275
|
buildCapabilityArgs
|
|
253
276
|
);
|
|
254
277
|
}
|
|
278
|
+
if (caps.analytics?.enabled) {
|
|
279
|
+
const analyticsCap = capabilities.analytics;
|
|
280
|
+
if (analyticsCap?.capability) {
|
|
281
|
+
client.analytics = analyticsCap.capability(
|
|
282
|
+
buildCapabilityArgs(void 0)
|
|
283
|
+
);
|
|
284
|
+
} else {
|
|
285
|
+
client.analytics = new HclAnalyticsCapability(
|
|
286
|
+
cache,
|
|
287
|
+
context,
|
|
288
|
+
config,
|
|
289
|
+
hclClient
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
if (caps.productAssociations?.enabled) {
|
|
294
|
+
client.productAssociations = resolveCapabilityWithFactory(
|
|
295
|
+
capabilities.productAssociations,
|
|
296
|
+
{
|
|
297
|
+
factory: new HclProductAssociationsFactory(ProductAssociationSchema),
|
|
298
|
+
capability: (args) => new HclProductAssociationsCapability(
|
|
299
|
+
args.cache,
|
|
300
|
+
args.context,
|
|
301
|
+
args.config,
|
|
302
|
+
args.hclClient,
|
|
303
|
+
args.factory
|
|
304
|
+
)
|
|
305
|
+
},
|
|
306
|
+
buildCapabilityArgs
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
if (caps.productRecommendations?.enabled) {
|
|
310
|
+
client.productRecommendations = resolveCapabilityWithFactory(
|
|
311
|
+
capabilities.productRecommendations,
|
|
312
|
+
{
|
|
313
|
+
factory: new HclProductRecommendationsFactory(
|
|
314
|
+
ProductRecommendationSchema
|
|
315
|
+
),
|
|
316
|
+
capability: (args) => new HclProductRecommendationsCapability(
|
|
317
|
+
args.cache,
|
|
318
|
+
args.context,
|
|
319
|
+
args.config,
|
|
320
|
+
args.hclClient,
|
|
321
|
+
args.factory
|
|
322
|
+
)
|
|
323
|
+
},
|
|
324
|
+
buildCapabilityArgs
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
if (caps.personalizationProfile?.enabled) {
|
|
328
|
+
client.personalizationProfile = resolveCapabilityWithFactory(
|
|
329
|
+
capabilities.personalizationProfile,
|
|
330
|
+
{
|
|
331
|
+
factory: new HclPersonalizationProfileFactory(
|
|
332
|
+
PersonalizationProfileSchema
|
|
333
|
+
),
|
|
334
|
+
capability: (args) => new HclPersonalizationProfileCapability(
|
|
335
|
+
args.cache,
|
|
336
|
+
args.context,
|
|
337
|
+
args.config,
|
|
338
|
+
args.hclClient,
|
|
339
|
+
args.factory
|
|
340
|
+
)
|
|
341
|
+
},
|
|
342
|
+
buildCapabilityArgs
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
if (caps.company?.enabled) {
|
|
346
|
+
client.company = resolveCapabilityWithFactory(
|
|
347
|
+
capabilities.company,
|
|
348
|
+
{
|
|
349
|
+
factory: new HclCompanyFactory(
|
|
350
|
+
CompanySchema,
|
|
351
|
+
CompanyPaginatedListSchema
|
|
352
|
+
),
|
|
353
|
+
capability: (args) => new HclCompanyCapability(
|
|
354
|
+
args.cache,
|
|
355
|
+
args.context,
|
|
356
|
+
args.config,
|
|
357
|
+
args.hclClient,
|
|
358
|
+
args.factory
|
|
359
|
+
)
|
|
360
|
+
},
|
|
361
|
+
buildCapabilityArgs
|
|
362
|
+
);
|
|
363
|
+
}
|
|
364
|
+
if (caps.store?.enabled) {
|
|
365
|
+
client.store = resolveCapabilityWithFactory(
|
|
366
|
+
capabilities.store,
|
|
367
|
+
{
|
|
368
|
+
factory: new HclStoreFactory(StoreSchema),
|
|
369
|
+
capability: (args) => new HclStoreCapability(
|
|
370
|
+
args.cache,
|
|
371
|
+
args.context,
|
|
372
|
+
args.config,
|
|
373
|
+
args.hclClient,
|
|
374
|
+
args.factory
|
|
375
|
+
)
|
|
376
|
+
},
|
|
377
|
+
buildCapabilityArgs
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
if (caps.productList?.enabled) {
|
|
381
|
+
client.productList = resolveCapabilityWithFactory(
|
|
382
|
+
capabilities.productList,
|
|
383
|
+
{
|
|
384
|
+
factory: new HclProductListFactory(
|
|
385
|
+
ProductListSchema,
|
|
386
|
+
ProductListItemSchema,
|
|
387
|
+
ProductListPaginatedResultsSchema,
|
|
388
|
+
ProductListItemPaginatedResultsSchema
|
|
389
|
+
),
|
|
390
|
+
capability: (args) => new HclProductListCapability(
|
|
391
|
+
args.cache,
|
|
392
|
+
args.context,
|
|
393
|
+
args.config,
|
|
394
|
+
args.hclClient,
|
|
395
|
+
args.factory
|
|
396
|
+
)
|
|
397
|
+
},
|
|
398
|
+
buildCapabilityArgs
|
|
399
|
+
);
|
|
400
|
+
}
|
|
255
401
|
return client;
|
|
256
402
|
};
|
|
257
403
|
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
class HclCompanyFactory {
|
|
2
|
+
companySchema;
|
|
3
|
+
companyPaginatedListSchema;
|
|
4
|
+
constructor(companySchema, companyPaginatedListSchema) {
|
|
5
|
+
this.companySchema = companySchema;
|
|
6
|
+
this.companyPaginatedListSchema = companyPaginatedListSchema;
|
|
7
|
+
}
|
|
8
|
+
parseCompany(_context, data) {
|
|
9
|
+
const result = {
|
|
10
|
+
identifier: {
|
|
11
|
+
taxIdentifier: data.taxPayerId ?? data.organizationId ?? data.orgEntityId ?? ""
|
|
12
|
+
},
|
|
13
|
+
name: data.organizationName ?? data.displayName ?? "",
|
|
14
|
+
dunsIdentifier: void 0,
|
|
15
|
+
tinIdentifier: data.legalId,
|
|
16
|
+
logo: void 0,
|
|
17
|
+
// state '0' = locked/blocked; any other value (or absent) = active
|
|
18
|
+
status: data.state === "0" ? "blocked" : "active",
|
|
19
|
+
pointOfContact: {
|
|
20
|
+
email: data.contactInfo?.email1 ?? "",
|
|
21
|
+
phone: data.contactInfo?.phone1
|
|
22
|
+
},
|
|
23
|
+
billingAddress: data.contactInfo ? this.parseOrgContact(data.contactInfo, "default") : this.parseOrgContact(
|
|
24
|
+
{
|
|
25
|
+
nickName: "default",
|
|
26
|
+
firstName: "",
|
|
27
|
+
lastName: "",
|
|
28
|
+
addressLine: [],
|
|
29
|
+
city: "",
|
|
30
|
+
stateOrProvinceName: "",
|
|
31
|
+
zipCode: "",
|
|
32
|
+
country: ""
|
|
33
|
+
},
|
|
34
|
+
"default"
|
|
35
|
+
),
|
|
36
|
+
alternateShippingAddresses: (data.addressBook ?? []).map(
|
|
37
|
+
(c, i) => this.parseOrgContact(c, c.nickName ?? `address-${i}`)
|
|
38
|
+
),
|
|
39
|
+
isCustomAddressesAllowed: false,
|
|
40
|
+
isSelfManagementOfShippingAddressesAllowed: false
|
|
41
|
+
};
|
|
42
|
+
return this.companySchema.parse(result);
|
|
43
|
+
}
|
|
44
|
+
parseCompanyPaginatedList(context, data, _query) {
|
|
45
|
+
const items = (data.organizationDataBeans ?? []).map(
|
|
46
|
+
(org) => this.parseCompany(context, org)
|
|
47
|
+
);
|
|
48
|
+
const pageSize = Math.max(1, items.length);
|
|
49
|
+
const result = {
|
|
50
|
+
identifier: {
|
|
51
|
+
paginationOptions: { pageNumber: 1, pageSize }
|
|
52
|
+
},
|
|
53
|
+
items,
|
|
54
|
+
totalCount: Number(data.recordSetTotal ?? items.length),
|
|
55
|
+
pageSize,
|
|
56
|
+
pageNumber: 1,
|
|
57
|
+
totalPages: 1
|
|
58
|
+
};
|
|
59
|
+
return this.companyPaginatedListSchema.parse(result);
|
|
60
|
+
}
|
|
61
|
+
parseOrgContact(contact, defaultNickName) {
|
|
62
|
+
return {
|
|
63
|
+
identifier: { nickName: contact.nickName ?? defaultNickName },
|
|
64
|
+
firstName: contact.firstName ?? "",
|
|
65
|
+
lastName: contact.lastName ?? "",
|
|
66
|
+
streetAddress: contact.addressLine?.[0] ?? "",
|
|
67
|
+
streetNumber: contact.addressLine?.[1] ?? "",
|
|
68
|
+
city: contact.city ?? "",
|
|
69
|
+
region: contact.stateOrProvinceName ?? "",
|
|
70
|
+
postalCode: contact.zipCode ?? "",
|
|
71
|
+
countryCode: contact.country ?? ""
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
export {
|
|
76
|
+
HclCompanyFactory
|
|
77
|
+
};
|
package/factories/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from "./cart/cart.factory.js";
|
|
2
2
|
export * from "./checkout/checkout.factory.js";
|
|
3
|
+
export * from "./company/company.factory.js";
|
|
3
4
|
export * from "./product/product.factory.js";
|
|
4
5
|
export * from "./category/category.factory.js";
|
|
5
6
|
export * from "./product-search/product-search.factory.js";
|
|
@@ -9,3 +10,8 @@ export * from "./identity/identity.factory.js";
|
|
|
9
10
|
export * from "./profile/profile.factory.js";
|
|
10
11
|
export * from "./order/order.factory.js";
|
|
11
12
|
export * from "./order-search/order-search.factory.js";
|
|
13
|
+
export * from "./product-associations/product-associations.factory.js";
|
|
14
|
+
export * from "./product-list/product-list.factory.js";
|
|
15
|
+
export * from "./product-recommendations/product-recommendations.factory.js";
|
|
16
|
+
export * from "./personalization-profile/personalization-profile.factory.js";
|
|
17
|
+
export * from "./store/store.factory.js";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
class HclPersonalizationProfileFactory {
|
|
2
|
+
personalizationProfileSchema;
|
|
3
|
+
constructor(personalizationProfileSchema) {
|
|
4
|
+
this.personalizationProfileSchema = personalizationProfileSchema;
|
|
5
|
+
}
|
|
6
|
+
parsePersonalizationProfile(_context, data) {
|
|
7
|
+
return this.personalizationProfileSchema.parse({
|
|
8
|
+
identifier: { key: data.personalizationId },
|
|
9
|
+
segments: data.segments,
|
|
10
|
+
blurb: ""
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export {
|
|
15
|
+
HclPersonalizationProfileFactory
|
|
16
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
class HclProductAssociationsFactory {
|
|
2
|
+
productAssociationSchema;
|
|
3
|
+
constructor(productAssociationSchema) {
|
|
4
|
+
this.productAssociationSchema = productAssociationSchema;
|
|
5
|
+
}
|
|
6
|
+
parseAssociation(_context, data) {
|
|
7
|
+
return this.productAssociationSchema.parse({
|
|
8
|
+
associationIdentifier: { key: data.partNumber },
|
|
9
|
+
associationReturnType: "idOnly",
|
|
10
|
+
product: { key: data.partNumber }
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export {
|
|
15
|
+
HclProductAssociationsFactory
|
|
16
|
+
};
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
const WISHLIST_TYPES = /* @__PURE__ */ new Set(["favorite", "wish", "shopping"]);
|
|
2
|
+
function encodeWishlistType(type, description) {
|
|
3
|
+
return `${type}:${description ?? ""}`;
|
|
4
|
+
}
|
|
5
|
+
function decodeWishlistType(raw) {
|
|
6
|
+
if (raw) {
|
|
7
|
+
const colonIdx = raw.indexOf(":");
|
|
8
|
+
if (colonIdx > 0) {
|
|
9
|
+
const prefix = raw.slice(0, colonIdx);
|
|
10
|
+
if (WISHLIST_TYPES.has(prefix)) {
|
|
11
|
+
const desc = raw.slice(colonIdx + 1);
|
|
12
|
+
return {
|
|
13
|
+
type: prefix,
|
|
14
|
+
description: desc || void 0
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return { type: "wish", description: raw || void 0 };
|
|
20
|
+
}
|
|
21
|
+
class HclProductListFactory {
|
|
22
|
+
productListSchema;
|
|
23
|
+
productListItemSchema;
|
|
24
|
+
productListPaginatedSchema;
|
|
25
|
+
productListItemPaginatedSchema;
|
|
26
|
+
constructor(productListSchema, productListItemSchema, productListPaginatedSchema, productListItemPaginatedSchema) {
|
|
27
|
+
this.productListSchema = productListSchema;
|
|
28
|
+
this.productListItemSchema = productListItemSchema;
|
|
29
|
+
this.productListPaginatedSchema = productListPaginatedSchema;
|
|
30
|
+
this.productListItemPaginatedSchema = productListItemPaginatedSchema;
|
|
31
|
+
}
|
|
32
|
+
parseProductList(_context, data) {
|
|
33
|
+
const key = data.uniqueID ?? data.externalIdentifier ?? "";
|
|
34
|
+
const { type, description } = decodeWishlistType(data.description);
|
|
35
|
+
const result = {
|
|
36
|
+
identifier: { key, listType: type },
|
|
37
|
+
type,
|
|
38
|
+
name: data.descriptionName ?? "",
|
|
39
|
+
description,
|
|
40
|
+
published: true
|
|
41
|
+
};
|
|
42
|
+
return this.productListSchema.parse(result);
|
|
43
|
+
}
|
|
44
|
+
parseProductListItem(_context, data) {
|
|
45
|
+
const result = {
|
|
46
|
+
identifier: { key: data.item.giftListItemID ?? "", list: data.list },
|
|
47
|
+
variant: { sku: data.item.productId ?? data.item.partNumber ?? "" },
|
|
48
|
+
quantity: Math.max(1, Number(data.item.quantityRequested ?? 1)),
|
|
49
|
+
order: 1
|
|
50
|
+
};
|
|
51
|
+
return this.productListItemSchema.parse(result);
|
|
52
|
+
}
|
|
53
|
+
parseProductListPaginatedResult(context, data, query) {
|
|
54
|
+
const items = (data.GiftList ?? []).map((w) => this.parseProductList(context, w)).filter(
|
|
55
|
+
(item) => item.identifier.listType === query.search.listType
|
|
56
|
+
);
|
|
57
|
+
const result = {
|
|
58
|
+
identifier: {
|
|
59
|
+
listType: query.search.listType,
|
|
60
|
+
paginationOptions: query.search.paginationOptions
|
|
61
|
+
},
|
|
62
|
+
items,
|
|
63
|
+
totalCount: items.length,
|
|
64
|
+
pageSize: Math.max(1, items.length),
|
|
65
|
+
pageNumber: 1,
|
|
66
|
+
totalPages: 1
|
|
67
|
+
};
|
|
68
|
+
return this.productListPaginatedSchema.parse(result);
|
|
69
|
+
}
|
|
70
|
+
parseProductListItemPaginatedResult(context, data, query) {
|
|
71
|
+
const rawItems = data.GiftList?.[0]?.item ?? [];
|
|
72
|
+
const items = rawItems.map(
|
|
73
|
+
(i) => this.parseProductListItem(context, { item: i, list: query.search.list })
|
|
74
|
+
);
|
|
75
|
+
const result = {
|
|
76
|
+
identifier: {
|
|
77
|
+
list: query.search.list,
|
|
78
|
+
paginationOptions: query.search.paginationOptions
|
|
79
|
+
},
|
|
80
|
+
items,
|
|
81
|
+
totalCount: Number(data.recordSetTotal ?? items.length),
|
|
82
|
+
pageSize: items.length,
|
|
83
|
+
pageNumber: 1,
|
|
84
|
+
totalPages: 1
|
|
85
|
+
};
|
|
86
|
+
return this.productListItemPaginatedSchema.parse(result);
|
|
87
|
+
}
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
// Requisition list parsers
|
|
90
|
+
// ---------------------------------------------------------------------------
|
|
91
|
+
parseRequisitionList(_context, data) {
|
|
92
|
+
const result = {
|
|
93
|
+
identifier: {
|
|
94
|
+
key: data.requisitionListId ?? "",
|
|
95
|
+
listType: "requisition"
|
|
96
|
+
},
|
|
97
|
+
type: "requisition",
|
|
98
|
+
name: data.name ?? "",
|
|
99
|
+
description: data.description,
|
|
100
|
+
published: true
|
|
101
|
+
};
|
|
102
|
+
return this.productListSchema.parse(result);
|
|
103
|
+
}
|
|
104
|
+
parseRequisitionListItem(_context, data) {
|
|
105
|
+
const result = {
|
|
106
|
+
identifier: {
|
|
107
|
+
key: data.item.requisitionListItemId ?? "",
|
|
108
|
+
list: data.list
|
|
109
|
+
},
|
|
110
|
+
variant: { sku: data.item.productId ?? data.item.partNumber ?? "" },
|
|
111
|
+
quantity: Math.max(1, Number(data.item.quantity ?? 1)),
|
|
112
|
+
order: 1
|
|
113
|
+
};
|
|
114
|
+
return this.productListItemSchema.parse(result);
|
|
115
|
+
}
|
|
116
|
+
parseRequisitionListPaginatedResult(context, data, query) {
|
|
117
|
+
const items = (data.resultList ?? []).map(
|
|
118
|
+
(r) => this.parseRequisitionList(context, r)
|
|
119
|
+
);
|
|
120
|
+
const result = {
|
|
121
|
+
identifier: {
|
|
122
|
+
listType: query.search.listType,
|
|
123
|
+
paginationOptions: query.search.paginationOptions
|
|
124
|
+
},
|
|
125
|
+
items,
|
|
126
|
+
totalCount: Number(data.recordSetTotal ?? items.length),
|
|
127
|
+
pageSize: Math.max(1, items.length),
|
|
128
|
+
pageNumber: 1,
|
|
129
|
+
totalPages: 1
|
|
130
|
+
};
|
|
131
|
+
return this.productListPaginatedSchema.parse(result);
|
|
132
|
+
}
|
|
133
|
+
parseRequisitionListItemPaginatedResult(context, data, query) {
|
|
134
|
+
const rawItems = data.resultList?.[0]?.item ?? [];
|
|
135
|
+
const items = rawItems.map(
|
|
136
|
+
(i) => this.parseRequisitionListItem(context, {
|
|
137
|
+
item: i,
|
|
138
|
+
list: query.search.list
|
|
139
|
+
})
|
|
140
|
+
);
|
|
141
|
+
const result = {
|
|
142
|
+
identifier: {
|
|
143
|
+
list: query.search.list,
|
|
144
|
+
paginationOptions: query.search.paginationOptions
|
|
145
|
+
},
|
|
146
|
+
items,
|
|
147
|
+
totalCount: Number(data.recordSetTotal ?? items.length),
|
|
148
|
+
pageSize: Math.max(1, items.length),
|
|
149
|
+
pageNumber: 1,
|
|
150
|
+
totalPages: 1
|
|
151
|
+
};
|
|
152
|
+
return this.productListItemPaginatedSchema.parse(result);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
export {
|
|
156
|
+
HclProductListFactory,
|
|
157
|
+
encodeWishlistType
|
|
158
|
+
};
|