@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.
Files changed (39) hide show
  1. package/capabilities/analytics.capability.js +98 -0
  2. package/capabilities/company.capability.js +307 -0
  3. package/capabilities/personalization-profile.capability.js +85 -0
  4. package/capabilities/product-associations.capability.js +117 -0
  5. package/capabilities/product-list.capability.js +665 -0
  6. package/capabilities/product-recommendations.capability.js +143 -0
  7. package/capabilities/store.capability.js +72 -0
  8. package/core/initialize.js +148 -2
  9. package/factories/company/company.factory.js +77 -0
  10. package/factories/index.js +6 -0
  11. package/factories/personalization-profile/personalization-profile.factory.js +16 -0
  12. package/factories/product-associations/product-associations.factory.js +16 -0
  13. package/factories/product-list/product-list.factory.js +158 -0
  14. package/factories/product-recommendations/product-recommendations.factory.js +17 -0
  15. package/factories/store/store.factory.js +18 -0
  16. package/index.js +7 -0
  17. package/package.json +2 -2
  18. package/schema/capabilities.schema.js +16 -2
  19. package/schema/configuration.schema.js +37 -1
  20. package/src/capabilities/analytics.capability.d.ts +17 -0
  21. package/src/capabilities/company.capability.d.ts +26 -0
  22. package/src/capabilities/personalization-profile.capability.d.ts +19 -0
  23. package/src/capabilities/product-associations.capability.d.ts +22 -0
  24. package/src/capabilities/product-list.capability.d.ts +42 -0
  25. package/src/capabilities/product-recommendations.capability.d.ts +29 -0
  26. package/src/capabilities/store.capability.d.ts +13 -0
  27. package/src/core/initialize.types.d.ts +7 -1
  28. package/src/factories/company/company.factory.d.ts +11 -0
  29. package/src/factories/index.d.ts +6 -0
  30. package/src/factories/personalization-profile/personalization-profile.factory.d.ts +11 -0
  31. package/src/factories/product-associations/product-associations.factory.d.ts +8 -0
  32. package/src/factories/product-list/product-list.factory.d.ts +40 -0
  33. package/src/factories/product-recommendations/product-recommendations.factory.d.ts +12 -0
  34. package/src/factories/store/store.factory.d.ts +8 -0
  35. package/src/index.d.ts +7 -0
  36. package/src/schema/capabilities.schema.d.ts +45 -1
  37. package/src/schema/configuration.schema.d.ts +24 -0
  38. package/src/schema/hcl.schema.d.ts +277 -1
  39. 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
+ };
@@ -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
+ };
@@ -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
+ };