@faststore/api 1.9.17 → 1.10.8
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/CHANGELOG.md +33 -0
- package/dist/api.cjs.development.js +102 -4
- package/dist/api.cjs.development.js.map +1 -1
- package/dist/api.cjs.production.min.js +1 -1
- package/dist/api.cjs.production.min.js.map +1 -1
- package/dist/api.esm.js +102 -4
- package/dist/api.esm.js.map +1 -1
- package/dist/platforms/vtex/clients/commerce/index.d.ts +13 -0
- package/dist/platforms/vtex/clients/commerce/types/Product.d.ts +174 -0
- package/dist/platforms/vtex/clients/commerce/types/SalesChannel.d.ts +24 -0
- package/dist/platforms/vtex/clients/index.d.ts +8 -0
- package/dist/platforms/vtex/loaders/index.d.ts +1 -0
- package/dist/platforms/vtex/loaders/salesChannel.d.ts +5 -0
- package/dist/platforms/vtex/resolvers/query.d.ts +3 -3
- package/dist/platforms/vtex/utils/facets.d.ts +14 -0
- package/package.json +3 -3
- package/src/__generated__/schema.ts +5 -1
- package/src/platforms/vtex/clients/commerce/index.ts +27 -1
- package/src/platforms/vtex/clients/commerce/types/Product.ts +199 -0
- package/src/platforms/vtex/clients/commerce/types/SalesChannel.ts +25 -0
- package/src/platforms/vtex/loaders/index.ts +3 -0
- package/src/platforms/vtex/loaders/salesChannel.ts +15 -0
- package/src/platforms/vtex/resolvers/aggregateOffer.ts +10 -1
- package/src/platforms/vtex/resolvers/offer.ts +10 -1
- package/src/platforms/vtex/resolvers/query.ts +39 -14
- package/src/platforms/vtex/utils/facets.ts +41 -0
|
@@ -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 {
|
|
2
|
-
import type { CategoryTree } from
|
|
3
|
-
import type { Context } from
|
|
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.
|
|
3
|
+
"version": "1.10.8",
|
|
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.
|
|
40
|
+
"shared": "^1.10.6",
|
|
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": "
|
|
49
|
+
"gitHead": "a1cee56b400b1309489843f7be6d1cf1b0eab65e"
|
|
50
50
|
}
|
|
@@ -341,8 +341,9 @@ export type StoreFacetRange = {
|
|
|
341
341
|
key: Scalars['String'];
|
|
342
342
|
/** Facet label. */
|
|
343
343
|
label: Scalars['String'];
|
|
344
|
+
/** Maximum facet range value. */
|
|
344
345
|
max: StoreFacetValueRange;
|
|
345
|
-
/**
|
|
346
|
+
/** Minimum facet range value. */
|
|
346
347
|
min: StoreFacetValueRange;
|
|
347
348
|
};
|
|
348
349
|
|
|
@@ -367,9 +368,12 @@ export type StoreFacetValueBoolean = {
|
|
|
367
368
|
value: Scalars['String'];
|
|
368
369
|
};
|
|
369
370
|
|
|
371
|
+
/** Search facet range value information. Used for minimum and maximum range values. */
|
|
370
372
|
export type StoreFacetValueRange = {
|
|
371
373
|
__typename?: 'StoreFacetValueRange';
|
|
374
|
+
/** Search facet range absolute value. */
|
|
372
375
|
absolute: Scalars['Float'];
|
|
376
|
+
/** Search facet range selected value. */
|
|
373
377
|
selected: Scalars['Float'];
|
|
374
378
|
};
|
|
375
379
|
|
|
@@ -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
|
+
};
|