@faststore/api 1.10.4 → 1.10.17

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.
@@ -1,3 +1,5 @@
1
+ import { FACET_CROSS_SELLING_MAP } from '../../utils/facets';
2
+ import type { PortalProduct } from './types/Product';
1
3
  import type { Context, Options } from '../../index';
2
4
  import type { Brand } from './types/Brand';
3
5
  import type { CategoryTree } from './types/CategoryTree';
@@ -7,8 +9,11 @@ import type { Region, RegionInput } from './types/Region';
7
9
  import type { Simulation, SimulationArgs, SimulationOptions } from './types/Simulation';
8
10
  import type { Session } from './types/Session';
9
11
  import type { Channel } from '../../utils/channel';
12
+ import type { SalesChannel } from './types/SalesChannel';
13
+ declare type ValueOf<T> = T extends Record<string, infer K> ? K : never;
10
14
  export declare const VtexCommerce: ({ account, environment }: Options, ctx: Context) => {
11
15
  catalog: {
16
+ salesChannel: (sc: string) => Promise<SalesChannel>;
12
17
  brand: {
13
18
  list: () => Promise<Brand[]>;
14
19
  };
@@ -18,6 +23,13 @@ export declare const VtexCommerce: ({ account, environment }: Options, ctx: Cont
18
23
  portal: {
19
24
  pagetype: (slug: string) => Promise<PortalPagetype>;
20
25
  };
26
+ products: {
27
+ crossselling: ({ type, productId, groupByProduct }: {
28
+ type: ValueOf<typeof FACET_CROSS_SELLING_MAP>;
29
+ productId: string;
30
+ groupByProduct?: boolean | undefined;
31
+ }) => Promise<PortalProduct[]>;
32
+ };
21
33
  };
22
34
  checkout: {
23
35
  simulation: (args: SimulationArgs, { salesChannel }?: SimulationOptions) => Promise<Simulation>;
@@ -42,3 +54,4 @@ export declare const VtexCommerce: ({ account, environment }: Options, ctx: Cont
42
54
  };
43
55
  session: (search: string) => Promise<Session>;
44
56
  };
57
+ export {};
@@ -0,0 +1,174 @@
1
+ export interface PortalProduct {
2
+ productId: string;
3
+ productName: string;
4
+ brand: string;
5
+ brandId: number;
6
+ brandImageUrl: null | string;
7
+ linkText: string;
8
+ productReference: string;
9
+ productReferenceCode: string;
10
+ categoryId: string;
11
+ productTitle: string;
12
+ metaTagDescription: string;
13
+ releaseDate: Date;
14
+ clusterHighlights: unknown;
15
+ productClusters: unknown;
16
+ searchableClusters: unknown;
17
+ categories: Category[];
18
+ categoriesIds: CategoriesId[];
19
+ link: string;
20
+ description: string;
21
+ items: Item[];
22
+ }
23
+ declare enum Category {
24
+ Office = "/Office/",
25
+ OfficeChairs = "/Office/Chairs/"
26
+ }
27
+ declare enum CategoriesId {
28
+ The9282 = "/9282/",
29
+ The92829296 = "/9282/9296/"
30
+ }
31
+ interface Item {
32
+ itemId: string;
33
+ name: string;
34
+ nameComplete: string;
35
+ complementName: string;
36
+ ean: string;
37
+ referenceId: ReferenceId[];
38
+ measurementUnit: MeasurementUnit;
39
+ unitMultiplier: number;
40
+ modalType: null;
41
+ isKit: boolean;
42
+ images: Image[];
43
+ sellers: Seller[];
44
+ videos: unknown[];
45
+ estimatedDateArrival: null;
46
+ }
47
+ interface Image {
48
+ imageId: string;
49
+ imageLabel: string;
50
+ imageTag: string;
51
+ imageUrl: string;
52
+ imageText: string;
53
+ imageLastModified: Date;
54
+ }
55
+ declare enum MeasurementUnit {
56
+ Un = "un"
57
+ }
58
+ interface ReferenceId {
59
+ key: Key;
60
+ value: string;
61
+ }
62
+ declare enum Key {
63
+ RefId = "RefId"
64
+ }
65
+ interface Seller {
66
+ sellerId: string;
67
+ sellerName: SellerName;
68
+ addToCartLink: string;
69
+ sellerDefault: boolean;
70
+ commertialOffer: CommertialOffer;
71
+ }
72
+ interface CommertialOffer {
73
+ deliverySlaSamplesPerRegion: DeliverySlaSamplesPerRegion;
74
+ installments: Installment[];
75
+ discountHighLight: unknown[];
76
+ giftSkuIds: unknown[];
77
+ teasers: unknown[];
78
+ buyTogether: unknown[];
79
+ itemMetadataAttachment: unknown[];
80
+ price: number;
81
+ listPrice: number;
82
+ priceWithoutDiscount: number;
83
+ rewardValue: number;
84
+ priceValidUntil: Date;
85
+ availableQuantity: number;
86
+ isAvailable: boolean;
87
+ tax: number;
88
+ deliverySlaSamples: DeliverySlaSample[];
89
+ getInfoErrorMessage: null;
90
+ cacheVersionUsedToCallCheckout: string;
91
+ paymentOptions: PaymentOptions;
92
+ }
93
+ interface DeliverySlaSample {
94
+ deliverySlaPerTypes: unknown[];
95
+ region: null;
96
+ }
97
+ interface DeliverySlaSamplesPerRegion {
98
+ the0: DeliverySlaSample;
99
+ }
100
+ interface Installment {
101
+ value: number;
102
+ interestRate: number;
103
+ totalValuePlusInterestRate: number;
104
+ numberOfInstallments: number;
105
+ paymentSystemName: PaymentSystemNameEnum;
106
+ paymentSystemGroupName: GroupName;
107
+ name: Name;
108
+ }
109
+ declare enum Name {
110
+ BoletoBancárioÀVista = "Boleto Banc\u00E1rio \u00E0 vista",
111
+ FreeÀVista = "Free \u00E0 vista"
112
+ }
113
+ declare enum GroupName {
114
+ BankInvoicePaymentGroup = "bankInvoicePaymentGroup",
115
+ Custom201PaymentGroupPaymentGroup = "custom201PaymentGroupPaymentGroup"
116
+ }
117
+ declare enum PaymentSystemNameEnum {
118
+ BoletoBancário = "Boleto Banc\u00E1rio",
119
+ Free = "Free"
120
+ }
121
+ interface PaymentOptions {
122
+ installmentOptions: InstallmentOption[];
123
+ paymentSystems: PaymentSystem[];
124
+ payments: unknown[];
125
+ giftCards: unknown[];
126
+ giftCardMessages: unknown[];
127
+ availableAccounts: unknown[];
128
+ availableTokens: unknown[];
129
+ }
130
+ interface InstallmentOption {
131
+ paymentSystem: string;
132
+ bin: null;
133
+ paymentName: PaymentSystemNameEnum;
134
+ paymentGroupName: GroupName;
135
+ value: number;
136
+ installments: InstallmentElement[];
137
+ }
138
+ interface InstallmentElement {
139
+ count: number;
140
+ hasInterestRate: boolean;
141
+ interestRate: number;
142
+ value: number;
143
+ total: number;
144
+ sellerMerchantInstallments?: InstallmentElement[];
145
+ id?: Id;
146
+ }
147
+ declare enum Id {
148
+ Storeframework = "STOREFRAMEWORK"
149
+ }
150
+ interface PaymentSystem {
151
+ id: number;
152
+ name: PaymentSystemNameEnum;
153
+ groupName: GroupName;
154
+ validator: null;
155
+ stringId: string;
156
+ template: Template;
157
+ requiresDocument: boolean;
158
+ isCustom: boolean;
159
+ description: Description | null;
160
+ requiresAuthentication: boolean;
161
+ dueDate: Date;
162
+ availablePayments: null;
163
+ }
164
+ declare enum Description {
165
+ FreePayToTestCheckoutPayments = "Free pay to test checkout payments"
166
+ }
167
+ declare enum Template {
168
+ BankInvoicePaymentGroupTemplate = "bankInvoicePaymentGroup-template",
169
+ Custom201PaymentGroupPaymentGroupTemplate = "custom201PaymentGroupPaymentGroup-template"
170
+ }
171
+ declare enum SellerName {
172
+ Vtex = "VTEX"
173
+ }
174
+ export {};
@@ -0,0 +1,24 @@
1
+ export interface SalesChannel {
2
+ Id: number;
3
+ Name: string;
4
+ IsActive: boolean;
5
+ ProductClusterId: null;
6
+ CountryCode: string;
7
+ CultureInfo: string;
8
+ TimeZone: string;
9
+ CurrencyCode: string;
10
+ CurrencySymbol: string;
11
+ CurrencyLocale: number;
12
+ CurrencyFormatInfo: CurrencyFormatInfo;
13
+ Origin: null;
14
+ Position: number;
15
+ ConditionRule: null;
16
+ CurrencyDecimalDigits: null;
17
+ }
18
+ export interface CurrencyFormatInfo {
19
+ CurrencyDecimalDigits: number;
20
+ CurrencyDecimalSeparator: string;
21
+ CurrencyGroupSeparator: string;
22
+ CurrencyGroupSize: number;
23
+ StartsWithCurrencySymbol: boolean;
24
+ }
@@ -9,6 +9,7 @@ export declare const getClients: (options: Options, ctx: Context) => {
9
9
  };
10
10
  commerce: {
11
11
  catalog: {
12
+ salesChannel: (sc: string) => Promise<import("./commerce/types/SalesChannel").SalesChannel>;
12
13
  brand: {
13
14
  list: () => Promise<import("./commerce/types/Brand").Brand[]>;
14
15
  };
@@ -18,6 +19,13 @@ export declare const getClients: (options: Options, ctx: Context) => {
18
19
  portal: {
19
20
  pagetype: (slug: string) => Promise<import("./commerce/types/Portal").PortalPagetype>;
20
21
  };
22
+ products: {
23
+ crossselling: ({ type, productId, groupByProduct }: {
24
+ type: "whoboughtalsobought" | "whosawalsosaw" | "similars" | "whosawalsobought" | "accessories" | "suggestions";
25
+ productId: string;
26
+ groupByProduct?: boolean | undefined;
27
+ }) => Promise<import("./commerce/types/Product").PortalProduct[]>;
28
+ };
21
29
  };
22
30
  checkout: {
23
31
  simulation: (args: import("./commerce/types/Simulation").SimulationArgs, { salesChannel }?: import("./commerce/types/Simulation").SimulationOptions) => Promise<import("./commerce/types/Simulation").Simulation>;
@@ -4,4 +4,5 @@ export declare const getLoaders: (options: Options, { clients }: Context) => {
4
4
  skuLoader: import("dataloader")<string, import("../utils/enhanceSku").EnhancedSku, string>;
5
5
  simulationLoader: import("dataloader")<import("../clients/commerce/types/Simulation").PayloadItem[], import("../clients/commerce/types/Simulation").Simulation, import("../clients/commerce/types/Simulation").PayloadItem[]>;
6
6
  collectionLoader: import("dataloader")<string, import("../clients/commerce/types/Portal").CollectionPageType, string>;
7
+ salesChannelLoader: import("dataloader")<string, import("../clients/commerce/types/SalesChannel").SalesChannel, string>;
7
8
  };
@@ -0,0 +1,5 @@
1
+ import DataLoader from "dataloader";
2
+ import { Options } from "..";
3
+ import { Clients } from "../clients";
4
+ import type { SalesChannel } from "./../clients/commerce/types/SalesChannel";
5
+ export declare const getSalesChannelLoader: (_: Options, clients: Clients) => DataLoader<string, SalesChannel, string>;
@@ -1,6 +1,6 @@
1
- import type { QueryProductArgs, QueryAllCollectionsArgs, QueryAllProductsArgs, QuerySearchArgs, QueryCollectionArgs } from '../../../__generated__/schema';
2
- import type { CategoryTree } from '../clients/commerce/types/CategoryTree';
3
- import type { Context } from '../index';
1
+ import type { QueryAllCollectionsArgs, QueryAllProductsArgs, QueryCollectionArgs, QueryProductArgs, QuerySearchArgs } from "../../../__generated__/schema";
2
+ import type { CategoryTree } from "../clients/commerce/types/CategoryTree";
3
+ import type { Context } from "../index";
4
4
  export declare const Query: {
5
5
  product: (_: unknown, { locator }: QueryProductArgs, ctx: Context) => Promise<import("../utils/enhanceSku").EnhancedSku>;
6
6
  collection: (_: unknown, { slug }: QueryCollectionArgs, ctx: Context) => Promise<import("../clients/commerce/types/Portal").CollectionPageType>;
@@ -2,6 +2,18 @@ export interface SelectedFacet {
2
2
  key: string;
3
3
  value: string;
4
4
  }
5
+ export interface CrossSellingFacet {
6
+ key: keyof typeof FACET_CROSS_SELLING_MAP;
7
+ value: string;
8
+ }
9
+ export declare const FACET_CROSS_SELLING_MAP: {
10
+ readonly buy: "whoboughtalsobought";
11
+ readonly view: "whosawalsosaw";
12
+ readonly similars: "similars";
13
+ readonly viewAndBought: "whosawalsobought";
14
+ readonly accessories: "accessories";
15
+ readonly suggestions: "suggestions";
16
+ };
5
17
  /**
6
18
  * Transform facets from the store to VTEX platform facets.
7
19
  * For instance, the channel in Store becomes trade-policy and regionId in VTEX's realm
@@ -14,6 +26,8 @@ export declare const transformSelectedFacet: ({ key, value }: SelectedFacet) =>
14
26
  value: string;
15
27
  };
16
28
  export declare const parseRange: (range: string) => [number, number] | null;
29
+ export declare const isCrossSelling: (x: string) => x is "similars" | "accessories" | "suggestions" | "buy" | "view" | "viewAndBought";
30
+ export declare const findCrossSelling: (facets?: SelectedFacet[] | null | undefined) => CrossSellingFacet | null;
17
31
  export declare const findSlug: (facets?: SelectedFacet[] | null | undefined) => string | null;
18
32
  export declare const findSkuId: (facets?: SelectedFacet[] | null | undefined) => string | null;
19
33
  export declare const findLocale: (facets?: SelectedFacet[] | null | undefined) => string | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@faststore/api",
3
- "version": "1.10.4",
3
+ "version": "1.10.17",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -37,7 +37,7 @@
37
37
  "express-graphql": "^0.12.0",
38
38
  "graphql": "^15.6.0",
39
39
  "jest-transform-graphql": "^2.1.0",
40
- "shared": "^1.9.14",
40
+ "shared": "^1.10.17",
41
41
  "ts-jest": "25.5.1",
42
42
  "tsdx": "^0.14.1",
43
43
  "tslib": "^2.3.1",
@@ -46,5 +46,5 @@
46
46
  "peerDependencies": {
47
47
  "graphql": "^15.6.0"
48
48
  },
49
- "gitHead": "d36bb24a69f08701be27ac2f98b07905cfe2d9dc"
49
+ "gitHead": "acf08434a1f27422e089c0db6e7a36455cbf02e5"
50
50
  }
@@ -1,4 +1,7 @@
1
+ import { FACET_CROSS_SELLING_MAP } from '../../utils/facets'
1
2
  import { fetchAPI } from '../fetch'
3
+
4
+ import type { PortalProduct } from './types/Product'
2
5
  import type { Context, Options } from '../../index'
3
6
  import type { Brand } from './types/Brand'
4
7
  import type { CategoryTree } from './types/CategoryTree'
@@ -12,6 +15,9 @@ import type {
12
15
  } from './types/Simulation'
13
16
  import type { Session } from './types/Session'
14
17
  import type { Channel } from '../../utils/channel'
18
+ import type { SalesChannel } from './types/SalesChannel'
19
+
20
+ type ValueOf<T> = T extends Record<string, infer K> ? K : never
15
21
 
16
22
  const BASE_INIT = {
17
23
  method: 'POST',
@@ -28,6 +34,8 @@ export const VtexCommerce = (
28
34
 
29
35
  return {
30
36
  catalog: {
37
+ salesChannel: (sc: string): Promise<SalesChannel> =>
38
+ fetchAPI(`${base}/api/catalog_system/pub/saleschannel/${sc}`),
31
39
  brand: {
32
40
  list: (): Promise<Brand[]> =>
33
41
  fetchAPI(`${base}/api/catalog_system/pub/brand/list`),
@@ -40,6 +48,24 @@ export const VtexCommerce = (
40
48
  pagetype: (slug: string): Promise<PortalPagetype> =>
41
49
  fetchAPI(`${base}/api/catalog_system/pub/portal/pagetype/${slug}`),
42
50
  },
51
+ products: {
52
+ crossselling: (
53
+ { type, productId, groupByProduct = true }: {
54
+ type: ValueOf<typeof FACET_CROSS_SELLING_MAP>;
55
+ productId: string;
56
+ groupByProduct?: boolean;
57
+ },
58
+ ): Promise<PortalProduct[]> => {
59
+ const params = new URLSearchParams({
60
+ sc: ctx.storage.channel.salesChannel,
61
+ groupByProduct: groupByProduct.toString(),
62
+ })
63
+
64
+ return fetchAPI(
65
+ `${base}/api/catalog_system/pub/products/crossselling/${type}/${productId}?${params}`,
66
+ )
67
+ },
68
+ },
43
69
  },
44
70
  checkout: {
45
71
  simulation: (
@@ -120,7 +146,7 @@ export const VtexCommerce = (
120
146
  ...BASE_INIT,
121
147
  body: JSON.stringify({ value }),
122
148
  method: 'PUT',
123
- }
149
+ },
124
150
  )
125
151
  },
126
152
  region: async ({
@@ -0,0 +1,199 @@
1
+ export interface PortalProduct {
2
+ productId: string;
3
+ productName: string;
4
+ brand: string;
5
+ brandId: number;
6
+ brandImageUrl: null | string;
7
+ linkText: string;
8
+ productReference: string;
9
+ productReferenceCode: string;
10
+ categoryId: string;
11
+ productTitle: string;
12
+ metaTagDescription: string;
13
+ releaseDate: Date;
14
+ clusterHighlights: unknown;
15
+ productClusters: unknown;
16
+ searchableClusters: unknown;
17
+ categories: Category[];
18
+ categoriesIds: CategoriesId[];
19
+ link: string;
20
+ description: string;
21
+ items: Item[];
22
+ }
23
+
24
+ enum Category {
25
+ Office = "/Office/",
26
+ OfficeChairs = "/Office/Chairs/",
27
+ }
28
+
29
+ enum CategoriesId {
30
+ The9282 = "/9282/",
31
+ The92829296 = "/9282/9296/",
32
+ }
33
+
34
+
35
+
36
+ interface Item {
37
+ itemId: string;
38
+ name: string;
39
+ nameComplete: string;
40
+ complementName: string;
41
+ ean: string;
42
+ referenceId: ReferenceId[];
43
+ measurementUnit: MeasurementUnit;
44
+ unitMultiplier: number;
45
+ modalType: null;
46
+ isKit: boolean;
47
+ images: Image[];
48
+ sellers: Seller[];
49
+ videos: unknown[];
50
+ estimatedDateArrival: null;
51
+ }
52
+
53
+ interface Image {
54
+ imageId: string;
55
+ imageLabel: string;
56
+ imageTag: string;
57
+ imageUrl: string;
58
+ imageText: string;
59
+ imageLastModified: Date;
60
+ }
61
+
62
+ enum MeasurementUnit {
63
+ Un = "un",
64
+ }
65
+
66
+ interface ReferenceId {
67
+ key: Key;
68
+ value: string;
69
+ }
70
+
71
+ enum Key {
72
+ RefId = "RefId",
73
+ }
74
+
75
+ interface Seller {
76
+ sellerId: string;
77
+ sellerName: SellerName;
78
+ addToCartLink: string;
79
+ sellerDefault: boolean;
80
+ commertialOffer: CommertialOffer;
81
+ }
82
+
83
+ interface CommertialOffer {
84
+ deliverySlaSamplesPerRegion: DeliverySlaSamplesPerRegion;
85
+ installments: Installment[];
86
+ discountHighLight: unknown[];
87
+ giftSkuIds: unknown[];
88
+ teasers: unknown[];
89
+ buyTogether: unknown[];
90
+ itemMetadataAttachment: unknown[];
91
+ price: number;
92
+ listPrice: number;
93
+ priceWithoutDiscount: number;
94
+ rewardValue: number;
95
+ priceValidUntil: Date;
96
+ availableQuantity: number;
97
+ isAvailable: boolean;
98
+ tax: number;
99
+ deliverySlaSamples: DeliverySlaSample[];
100
+ getInfoErrorMessage: null;
101
+ cacheVersionUsedToCallCheckout: string;
102
+ paymentOptions: PaymentOptions;
103
+ }
104
+
105
+ interface DeliverySlaSample {
106
+ deliverySlaPerTypes: unknown[];
107
+ region: null;
108
+ }
109
+
110
+ interface DeliverySlaSamplesPerRegion {
111
+ the0: DeliverySlaSample;
112
+ }
113
+
114
+ interface Installment {
115
+ value: number;
116
+ interestRate: number;
117
+ totalValuePlusInterestRate: number;
118
+ numberOfInstallments: number;
119
+ paymentSystemName: PaymentSystemNameEnum;
120
+ paymentSystemGroupName: GroupName;
121
+ name: Name;
122
+ }
123
+
124
+ enum Name {
125
+ BoletoBancárioÀVista = "Boleto Bancário à vista",
126
+ FreeÀVista = "Free à vista",
127
+ }
128
+
129
+ enum GroupName {
130
+ BankInvoicePaymentGroup = "bankInvoicePaymentGroup",
131
+ Custom201PaymentGroupPaymentGroup = "custom201PaymentGroupPaymentGroup",
132
+ }
133
+
134
+ enum PaymentSystemNameEnum {
135
+ BoletoBancário = "Boleto Bancário",
136
+ Free = "Free",
137
+ }
138
+
139
+ interface PaymentOptions {
140
+ installmentOptions: InstallmentOption[];
141
+ paymentSystems: PaymentSystem[];
142
+ payments: unknown[];
143
+ giftCards: unknown[];
144
+ giftCardMessages: unknown[];
145
+ availableAccounts: unknown[];
146
+ availableTokens: unknown[];
147
+ }
148
+
149
+ interface InstallmentOption {
150
+ paymentSystem: string;
151
+ bin: null;
152
+ paymentName: PaymentSystemNameEnum;
153
+ paymentGroupName: GroupName;
154
+ value: number;
155
+ installments: InstallmentElement[];
156
+ }
157
+
158
+ interface InstallmentElement {
159
+ count: number;
160
+ hasInterestRate: boolean;
161
+ interestRate: number;
162
+ value: number;
163
+ total: number;
164
+ sellerMerchantInstallments?: InstallmentElement[];
165
+ id?: Id;
166
+ }
167
+
168
+ enum Id {
169
+ Storeframework = "STOREFRAMEWORK",
170
+ }
171
+
172
+ interface PaymentSystem {
173
+ id: number;
174
+ name: PaymentSystemNameEnum;
175
+ groupName: GroupName;
176
+ validator: null;
177
+ stringId: string;
178
+ template: Template;
179
+ requiresDocument: boolean;
180
+ isCustom: boolean;
181
+ description: Description | null;
182
+ requiresAuthentication: boolean;
183
+ dueDate: Date;
184
+ availablePayments: null;
185
+ }
186
+
187
+ enum Description {
188
+ FreePayToTestCheckoutPayments = "Free pay to test checkout payments",
189
+ }
190
+
191
+ enum Template {
192
+ BankInvoicePaymentGroupTemplate = "bankInvoicePaymentGroup-template",
193
+ Custom201PaymentGroupPaymentGroupTemplate =
194
+ "custom201PaymentGroupPaymentGroup-template",
195
+ }
196
+
197
+ enum SellerName {
198
+ Vtex = "VTEX",
199
+ }
@@ -0,0 +1,25 @@
1
+ export interface SalesChannel {
2
+ Id: number;
3
+ Name: string;
4
+ IsActive: boolean;
5
+ ProductClusterId: null;
6
+ CountryCode: string;
7
+ CultureInfo: string;
8
+ TimeZone: string;
9
+ CurrencyCode: string;
10
+ CurrencySymbol: string;
11
+ CurrencyLocale: number;
12
+ CurrencyFormatInfo: CurrencyFormatInfo;
13
+ Origin: null;
14
+ Position: number;
15
+ ConditionRule: null;
16
+ CurrencyDecimalDigits: null;
17
+ }
18
+
19
+ export interface CurrencyFormatInfo {
20
+ CurrencyDecimalDigits: number;
21
+ CurrencyDecimalSeparator: string;
22
+ CurrencyGroupSeparator: string;
23
+ CurrencyGroupSize: number;
24
+ StartsWithCurrencySymbol: boolean;
25
+ }
@@ -1,3 +1,4 @@
1
+ import { getSalesChannelLoader } from './salesChannel';
1
2
  import { getSimulationLoader } from './simulation'
2
3
  import { getSkuLoader } from './sku'
3
4
  import { getCollectionLoader } from './collection'
@@ -9,10 +10,12 @@ export const getLoaders = (options: Options, { clients }: Context) => {
9
10
  const skuLoader = getSkuLoader(options, clients)
10
11
  const simulationLoader = getSimulationLoader(options, clients)
11
12
  const collectionLoader = getCollectionLoader(options, clients)
13
+ const salesChannelLoader = getSalesChannelLoader(options, clients)
12
14
 
13
15
  return {
14
16
  skuLoader,
15
17
  simulationLoader,
16
18
  collectionLoader,
19
+ salesChannelLoader
17
20
  }
18
21
  }
@@ -0,0 +1,15 @@
1
+ import DataLoader from "dataloader";
2
+
3
+ import { Options } from "..";
4
+ import { Clients } from "../clients";
5
+
6
+ import type { SalesChannel } from "./../clients/commerce/types/SalesChannel";
7
+
8
+ export const getSalesChannelLoader = (_: Options, clients: Clients) => {
9
+ const loader = async (channels: readonly string[]) =>
10
+ Promise.all(
11
+ channels.map((sc) => clients.commerce.catalog.salesChannel(sc)),
12
+ );
13
+
14
+ return new DataLoader<string, SalesChannel>(loader);
15
+ };
@@ -20,6 +20,15 @@ export const StoreAggregateOffer: Record<string, Resolver<Root>> & {
20
20
  return lowOffer ? price(lowOffer) : 0
21
21
  },
22
22
  offerCount: (offers) => offers.length,
23
- priceCurrency: () => '',
23
+ priceCurrency: async (_, __, ctx) => {
24
+ const {
25
+ loaders: { salesChannelLoader },
26
+ storage: { channel }
27
+ } = ctx
28
+
29
+ const sc = await salesChannelLoader.load(channel.salesChannel);
30
+
31
+ return sc.CurrencyCode ?? '';
32
+ },
24
33
  offers: (offers) => offers,
25
34
  }
@@ -24,7 +24,16 @@ const isOrderFormItem = (item: Root): item is OrderFormProduct =>
24
24
  'skuName' in item
25
25
 
26
26
  export const StoreOffer: Record<string, Resolver<Root>> = {
27
- priceCurrency: () => '',
27
+ priceCurrency: async (_, __, ctx) => {
28
+ const {
29
+ loaders: { salesChannelLoader },
30
+ storage: { channel }
31
+ } = ctx
32
+
33
+ const sc = await salesChannelLoader.load(channel.salesChannel);
34
+
35
+ return sc.CurrencyCode ?? '';
36
+ },
28
37
  priceValidUntil: (root) => {
29
38
  if (isSearchItem(root)) {
30
39
  return root.PriceValidUntil ?? ''