@faststore/api 2.2.0-alpha.1 → 2.2.0-alpha.12

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/dist/index.d.ts CHANGED
@@ -124,7 +124,7 @@ export declare const getResolvers: (options: Options) => {
124
124
  parentAssemblyBinding: import("./__generated__/schema").Maybe<string>;
125
125
  productCategoryIds: string;
126
126
  priceTags: string[];
127
- manualPrice: number;
127
+ manualPrice: number | null;
128
128
  measurementUnit: string;
129
129
  additionalInfo: {
130
130
  brandName: string;
@@ -139,7 +139,7 @@ export declare const getResolvers: (options: Options) => {
139
139
  sellerChain: string[];
140
140
  availability: string;
141
141
  unitMultiplier: number;
142
- skuSpecifications: import("./platforms/vtex/clients/commerce/types/OrderForm").SKUSpecification[];
142
+ skuSpecifications?: import("./platforms/vtex/clients/commerce/types/OrderForm").SKUSpecification[] | null | undefined;
143
143
  priceDefinition: {
144
144
  calculatedSellingPrice: number;
145
145
  sellingPrices: import("./platforms/vtex/clients/commerce/types/OrderForm").SellingPrice[];
@@ -31,7 +31,7 @@ export interface OrderFormItem {
31
31
  parentAssemblyBinding: string | null;
32
32
  productCategoryIds: string;
33
33
  priceTags: string[];
34
- manualPrice: number;
34
+ manualPrice: number | null;
35
35
  measurementUnit: string;
36
36
  additionalInfo: {
37
37
  brandName: string;
@@ -46,7 +46,7 @@ export interface OrderFormItem {
46
46
  sellerChain: string[];
47
47
  availability: string;
48
48
  unitMultiplier: number;
49
- skuSpecifications: SKUSpecification[];
49
+ skuSpecifications?: SKUSpecification[] | null;
50
50
  priceDefinition: {
51
51
  calculatedSellingPrice: number;
52
52
  sellingPrices: SellingPrice[];
@@ -127,7 +127,7 @@ export interface OrderForm {
127
127
  currencyGroupSize: number;
128
128
  startsWithCurrencySymbol: boolean;
129
129
  };
130
- currencyLocale: string;
130
+ currencyLocale: number;
131
131
  currencySymbol: string;
132
132
  saveUserData: boolean;
133
133
  timeZone: string;
@@ -138,7 +138,7 @@ export interface OrderForm {
138
138
  customData: OrderFormCustomData | null;
139
139
  itemMetadata: {
140
140
  items: MetadataItem[];
141
- };
141
+ } | null;
142
142
  hooksData: any | null;
143
143
  ratesAndBenefitsData: {
144
144
  rateAndBenefitsIdentifiers: any[];
@@ -217,21 +217,21 @@ export interface PaymentData {
217
217
  availableTokens: any[];
218
218
  }
219
219
  export interface ClientProfileData {
220
- email: string;
221
- firstName: string;
222
- lastName: string;
223
- document: string;
224
- documentType: string;
225
- phone: string;
226
- corporateName: string;
227
- tradeName: string;
228
- corporateDocument: string;
229
- stateInscription: string;
230
- corporatePhone: string;
220
+ email: string | null;
221
+ firstName: string | null;
222
+ lastName: string | null;
223
+ document: string | null;
224
+ documentType: string | null;
225
+ phone: string | null;
226
+ corporateName: string | null;
227
+ tradeName: string | null;
228
+ corporateDocument: string | null;
229
+ stateInscription: string | null;
230
+ corporatePhone: string | null;
231
231
  isCorporate: boolean;
232
232
  profileCompleteOnLoading: boolean;
233
233
  profileErrorOnLoading: boolean;
234
- customerClass: string;
234
+ customerClass: string | null;
235
235
  }
236
236
  export interface ShippingData {
237
237
  address: CheckoutAddress | null;
@@ -295,7 +295,7 @@ export interface AvailableDeliveryWindows {
295
295
  startDateUtc: string;
296
296
  endDateUtc: string;
297
297
  price: number;
298
- listPrice: number;
298
+ lisPrice?: number;
299
299
  tax: number;
300
300
  }
301
301
  export interface DeliveryId {
@@ -152,7 +152,7 @@ export declare const getResolvers: (_: Options) => {
152
152
  parentAssemblyBinding: string | null;
153
153
  productCategoryIds: string;
154
154
  priceTags: string[];
155
- manualPrice: number;
155
+ manualPrice: number | null;
156
156
  measurementUnit: string;
157
157
  additionalInfo: {
158
158
  brandName: string;
@@ -167,7 +167,7 @@ export declare const getResolvers: (_: Options) => {
167
167
  sellerChain: string[];
168
168
  availability: string;
169
169
  unitMultiplier: number;
170
- skuSpecifications: import("./clients/commerce/types/OrderForm").SKUSpecification[];
170
+ skuSpecifications?: import("./clients/commerce/types/OrderForm").SKUSpecification[] | null | undefined;
171
171
  priceDefinition: {
172
172
  calculatedSellingPrice: number;
173
173
  sellingPrices: import("./clients/commerce/types/OrderForm").SellingPrice[];
@@ -25,7 +25,7 @@ export declare const Mutation: {
25
25
  parentAssemblyBinding: string | null;
26
26
  productCategoryIds: string;
27
27
  priceTags: string[];
28
- manualPrice: number;
28
+ manualPrice: number | null;
29
29
  measurementUnit: string;
30
30
  additionalInfo: {
31
31
  brandName: string;
@@ -40,7 +40,7 @@ export declare const Mutation: {
40
40
  sellerChain: string[];
41
41
  availability: string;
42
42
  unitMultiplier: number;
43
- skuSpecifications: import("../clients/commerce/types/OrderForm").SKUSpecification[];
43
+ skuSpecifications?: import("../clients/commerce/types/OrderForm").SKUSpecification[] | null | undefined;
44
44
  priceDefinition: {
45
45
  calculatedSellingPrice: number;
46
46
  sellingPrices: import("../clients/commerce/types/OrderForm").SellingPrice[];
@@ -39,7 +39,7 @@ export declare const validateCart: (_: unknown, { cart: { order }, session }: Mu
39
39
  parentAssemblyBinding: string | null;
40
40
  productCategoryIds: string;
41
41
  priceTags: string[];
42
- manualPrice: number;
42
+ manualPrice: number | null;
43
43
  measurementUnit: string;
44
44
  additionalInfo: {
45
45
  brandName: string;
@@ -54,7 +54,7 @@ export declare const validateCart: (_: unknown, { cart: { order }, session }: Mu
54
54
  sellerChain: string[];
55
55
  availability: string;
56
56
  unitMultiplier: number;
57
- skuSpecifications: import("../clients/commerce/types/OrderForm").SKUSpecification[];
57
+ skuSpecifications?: import("../clients/commerce/types/OrderForm").SKUSpecification[] | null | undefined;
58
58
  priceDefinition: {
59
59
  calculatedSellingPrice: number;
60
60
  sellingPrices: import("../clients/commerce/types/OrderForm").SellingPrice[];
@@ -0,0 +1,17 @@
1
+ import sanitizeHtmlLib from 'sanitize-html';
2
+ /**
3
+ * For now, we're using sanitize-html's default set
4
+ * of allowed tags and attributes, which don't even include img elements
5
+ *
6
+ * It is known many client depends on pontentially vulnerable tags, such as script tags
7
+ * We chose to be restrictive at first, and document those restrictions later.
8
+ *
9
+ * When expanding the set of allowed tags and attributes, please consider performance, privacy and security.
10
+ *
11
+ * This possibily breaks compatibility with Portal and Store Framework,
12
+ * which both allows an enormous amount of tags and attributes
13
+ *
14
+ * This was a thoughtful decision that can be reviewed in the future given
15
+ * research was made to back up those changes.
16
+ */
17
+ export declare const sanitizeHtml: (dirty: Parameters<typeof sanitizeHtmlLib>[0], options?: Parameters<typeof sanitizeHtmlLib>[1]) => string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@faststore/api",
3
- "version": "2.2.0-alpha.1",
3
+ "version": "2.2.0-alpha.12",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -32,15 +32,17 @@
32
32
  "dataloader": "^2.1.0",
33
33
  "fast-deep-equal": "^3.1.3",
34
34
  "isomorphic-unfetch": "^3.1.0",
35
- "p-limit": "^3.1.0"
35
+ "p-limit": "^3.1.0",
36
+ "sanitize-html": "^2.11.0"
36
37
  },
37
38
  "devDependencies": {
38
39
  "@envelop/core": "^2.6.0",
39
- "@faststore/eslint-config": "^2.2.0-alpha.1",
40
- "@faststore/shared": "^2.2.0-alpha.1",
40
+ "@faststore/eslint-config": "^2.2.0-alpha.12",
41
+ "@faststore/shared": "^2.2.0-alpha.12",
41
42
  "@graphql-codegen/cli": "2.2.0",
42
43
  "@graphql-codegen/typescript": "2.2.2",
43
44
  "@types/express": "^4.17.16",
45
+ "@types/sanitize-html": "^2.9.1",
44
46
  "concurrently": "^6.2.1",
45
47
  "eslint": "7.32.0",
46
48
  "express": "^4.17.3",
@@ -56,5 +58,5 @@
56
58
  "@envelop/core": "^1 || ^2",
57
59
  "graphql": "^15.6.0"
58
60
  },
59
- "gitHead": "6eff908883fa54cb72d548b12a610490df833804"
61
+ "gitHead": "7f27647c52ad0690389e72db639562b167a09c49"
60
62
  }
@@ -121,7 +121,6 @@ export const VtexCommerce = (
121
121
  selectedAddresses: selectedAddresses,
122
122
  clearAddressIfPostalCodeNotFound: incrementAddress,
123
123
  }
124
-
125
124
  return fetchAPI(
126
125
  `${base}/api/checkout/pub/orderForm/${id}/attachments/shippingData`,
127
126
  {
@@ -149,10 +148,19 @@ export const VtexCommerce = (
149
148
  refreshOutdatedData: refreshOutdatedData.toString(),
150
149
  sc: salesChannel,
151
150
  })
151
+ const requestInit: RequestInit = ctx.headers
152
+ ? {
153
+ ...BASE_INIT,
154
+ headers: {
155
+ 'content-type': 'application/json',
156
+ cookie: ctx.headers.cookie,
157
+ },
158
+ }
159
+ : BASE_INIT
152
160
 
153
161
  return fetchAPI(
154
162
  `${base}/api/checkout/pub/orderForm/${id}?${params.toString()}`,
155
- BASE_INIT
163
+ requestInit
156
164
  )
157
165
  },
158
166
  updateOrderFormItems: ({
@@ -173,16 +181,31 @@ export const VtexCommerce = (
173
181
  sc: salesChannel,
174
182
  })
175
183
 
184
+ const items = JSON.stringify({
185
+ orderItems,
186
+ noSplitItem: !shouldSplitItem,
187
+ })
188
+
189
+ const requestInit: RequestInit = ctx.headers
190
+ ? {
191
+ headers: {
192
+ 'content-type': 'application/json',
193
+ cookie: ctx.headers.cookie,
194
+ },
195
+ body: items,
196
+ method: 'PATCH',
197
+ }
198
+ : {
199
+ headers: {
200
+ 'content-type': 'application/json',
201
+ },
202
+ body: items,
203
+ method: 'PATCH',
204
+ }
205
+
176
206
  return fetchAPI(
177
207
  `${base}/api/checkout/pub/orderForm/${id}/items?${params}`,
178
- {
179
- ...BASE_INIT,
180
- body: JSON.stringify({
181
- orderItems,
182
- noSplitItem: !shouldSplitItem,
183
- }),
184
- method: 'PATCH',
185
- }
208
+ requestInit
186
209
  )
187
210
  },
188
211
  setCustomData: ({
@@ -33,7 +33,7 @@ export interface OrderFormItem {
33
33
  parentAssemblyBinding: string | null
34
34
  productCategoryIds: string
35
35
  priceTags: string[]
36
- manualPrice: number
36
+ manualPrice: number | null
37
37
  measurementUnit: string
38
38
  additionalInfo: {
39
39
  brandName: string
@@ -48,7 +48,7 @@ export interface OrderFormItem {
48
48
  sellerChain: string[]
49
49
  availability: string
50
50
  unitMultiplier: number
51
- skuSpecifications: SKUSpecification[]
51
+ skuSpecifications?: SKUSpecification[] | null
52
52
  priceDefinition: {
53
53
  calculatedSellingPrice: number
54
54
  sellingPrices: SellingPrice[]
@@ -135,7 +135,7 @@ export interface OrderForm {
135
135
  currencyGroupSize: number
136
136
  startsWithCurrencySymbol: boolean
137
137
  }
138
- currencyLocale: string
138
+ currencyLocale: number
139
139
  currencySymbol: string
140
140
  saveUserData: boolean
141
141
  timeZone: string
@@ -146,7 +146,7 @@ export interface OrderForm {
146
146
  customData: OrderFormCustomData | null
147
147
  itemMetadata: {
148
148
  items: MetadataItem[]
149
- }
149
+ } | null
150
150
  hooksData: any | null
151
151
  ratesAndBenefitsData: {
152
152
  rateAndBenefitsIdentifiers: any[]
@@ -229,21 +229,21 @@ export interface PaymentData {
229
229
  }
230
230
 
231
231
  export interface ClientProfileData {
232
- email: string
233
- firstName: string
234
- lastName: string
235
- document: string
236
- documentType: string
237
- phone: string
238
- corporateName: string
239
- tradeName: string
240
- corporateDocument: string
241
- stateInscription: string
242
- corporatePhone: string
232
+ email: string | null
233
+ firstName: string | null
234
+ lastName: string | null
235
+ document: string | null
236
+ documentType: string | null
237
+ phone: string | null
238
+ corporateName: string | null
239
+ tradeName: string | null
240
+ corporateDocument: string | null
241
+ stateInscription: string | null
242
+ corporatePhone: string | null
243
243
  isCorporate: boolean
244
244
  profileCompleteOnLoading: boolean
245
245
  profileErrorOnLoading: boolean
246
- customerClass: string
246
+ customerClass: string | null
247
247
  }
248
248
 
249
249
  export interface ShippingData {
@@ -314,7 +314,7 @@ export interface AvailableDeliveryWindows {
314
314
  startDateUtc: string,
315
315
  endDateUtc: string,
316
316
  price: number,
317
- listPrice: number,
317
+ lisPrice?: number,
318
318
  tax: number,
319
319
  }
320
320
 
@@ -35,7 +35,7 @@ export interface Options {
35
35
  channel: string
36
36
  locale: string
37
37
  hideUnavailableItems: boolean
38
- incrementAddress: boolean,
38
+ incrementAddress: boolean
39
39
  flags?: FeatureFlags
40
40
  }
41
41
 
@@ -372,7 +372,6 @@ export const validateCart = async (
372
372
  if (changes.length === 0) {
373
373
  return null
374
374
  }
375
-
376
375
  // Step4: Apply delta changes to order form
377
376
  const updatedOrderForm = await commerce.checkout
378
377
  // update orderForm items
@@ -1,8 +1,18 @@
1
1
  import type { Product, Item } from '../clients/search/types/ProductSearchResult'
2
+ import { sanitizeHtml } from './sanitizeHtml'
2
3
 
3
4
  export type EnhancedSku = Item & { isVariantOf: Product }
4
5
 
6
+ function sanitizeProduct(product: Product): Product {
7
+ return {
8
+ ...product,
9
+ description: product.description
10
+ ? sanitizeHtml(product.description)
11
+ : product.description,
12
+ }
13
+ }
14
+
5
15
  export const enhanceSku = (item: Item, product: Product): EnhancedSku => ({
6
16
  ...item,
7
- isVariantOf: product,
17
+ isVariantOf: sanitizeProduct(product),
8
18
  })
@@ -0,0 +1,21 @@
1
+ import sanitizeHtmlLib from 'sanitize-html'
2
+
3
+ /**
4
+ * For now, we're using sanitize-html's default set
5
+ * of allowed tags and attributes, which don't even include img elements
6
+ *
7
+ * It is known many client depends on pontentially vulnerable tags, such as script tags
8
+ * We chose to be restrictive at first, and document those restrictions later.
9
+ *
10
+ * When expanding the set of allowed tags and attributes, please consider performance, privacy and security.
11
+ *
12
+ * This possibily breaks compatibility with Portal and Store Framework,
13
+ * which both allows an enormous amount of tags and attributes
14
+ *
15
+ * This was a thoughtful decision that can be reviewed in the future given
16
+ * research was made to back up those changes.
17
+ */
18
+ export const sanitizeHtml = (
19
+ dirty: Parameters<typeof sanitizeHtmlLib>[0],
20
+ options?: Parameters<typeof sanitizeHtmlLib>[1]
21
+ ) => sanitizeHtmlLib(dirty, options)
@@ -16,42 +16,23 @@ export const shouldUpdateShippingData = (
16
16
  return { updateShipping: false, addressChanged: false }
17
17
  }
18
18
 
19
- const selectedAddress = orderForm.shippingData?.selectedAddresses[0]
20
-
21
- if (checkPostalCode(selectedAddress, session.postalCode)) {
22
- return { updateShipping: true, addressChanged: true }
19
+ if (!hasItems(orderForm)) {
20
+ return { updateShipping: false, addressChanged: false }
23
21
  }
24
22
 
23
+ const [selectedAddress] = orderForm?.shippingData?.selectedAddresses ?? []
25
24
  if (
26
- checkGeoCoordinates(
27
- selectedAddress,
28
- session.geoCoordinates,
29
- session.postalCode
30
- )
25
+ checkPostalCode(selectedAddress, session.postalCode) ||
26
+ checkGeoCoordinates(selectedAddress, session.geoCoordinates) ||
27
+ checkAddressType(selectedAddress, session.addressType)
31
28
  ) {
32
29
  return { updateShipping: true, addressChanged: true }
33
30
  }
34
31
 
35
- if (checkAddressType(selectedAddress, session.addressType)) {
36
- return { updateShipping: true, addressChanged: true }
37
- }
38
-
39
- if (!hasItems(orderForm)) {
40
- return { updateShipping: false, addressChanged: false }
41
- }
42
-
43
32
  // The logisticsInfo will always exist if there´s at least one item inside the cart
44
33
  const { logisticsInfo } = orderForm.shippingData!
45
34
 
46
- if (shouldUpdateDeliveryChannel(logisticsInfo, session)) {
47
- return { updateShipping: true, addressChanged: false }
48
- }
49
-
50
- if (shouldUpdateDeliveryMethod(logisticsInfo, session)) {
51
- return { updateShipping: true, addressChanged: false }
52
- }
53
-
54
- if (shouldUpdateDeliveryWindow(logisticsInfo, session)) {
35
+ if (shouldUpdateDeliveryInfo(logisticsInfo, session)) {
55
36
  return { updateShipping: true, addressChanged: false }
56
37
  }
57
38
  return { updateShipping: false, addressChanged: false }
@@ -61,15 +42,13 @@ export const shouldUpdateShippingData = (
61
42
  const hasSessionPostalCodeOrGeoCoordinates = (session: IStoreSession) => {
62
43
  return (
63
44
  !!session.postalCode ||
64
- (session.geoCoordinates &&
65
- session.geoCoordinates.latitude &&
66
- session.geoCoordinates.longitude)
45
+ (session.geoCoordinates?.latitude && session.geoCoordinates?.longitude)
67
46
  )
68
47
  }
69
48
 
70
49
  // Validate if theres a difference between the session postal code and orderForm postal code
71
50
  const checkPostalCode = (
72
- address: CheckoutAddress | null | undefined,
51
+ address: CheckoutAddress | null,
73
52
  postalCode: string | null | undefined
74
53
  ) => {
75
54
  return typeof postalCode === 'string' && address?.postalCode !== postalCode
@@ -77,21 +56,19 @@ const checkPostalCode = (
77
56
 
78
57
  // Validate if theres a difference between the session geoCoords and orderForm geoCoords
79
58
  const checkGeoCoordinates = (
80
- address: CheckoutAddress | null | undefined,
81
- geoCoordinates: IStoreGeoCoordinates | null | undefined,
82
- postalCode: string | null | undefined
59
+ address: CheckoutAddress | null,
60
+ geoCoordinates: IStoreGeoCoordinates | null | undefined
83
61
  ) => {
84
62
  return (
85
63
  typeof geoCoordinates?.latitude === 'number' &&
86
64
  typeof geoCoordinates?.longitude === 'number' &&
87
65
  (address?.geoCoordinates[0] !== geoCoordinates?.longitude ||
88
- address?.geoCoordinates[1] !== geoCoordinates?.latitude) &&
89
- address?.postalCode !== postalCode
66
+ address?.geoCoordinates[1] !== geoCoordinates?.latitude)
90
67
  )
91
68
  }
92
69
 
93
70
  const checkAddressType = (
94
- address: CheckoutAddress | null | undefined,
71
+ address: CheckoutAddress | null,
95
72
  addressType: string | null | undefined
96
73
  ) => {
97
74
  return typeof addressType === 'string' && address?.addressType !== addressType
@@ -102,73 +79,43 @@ const hasItems = (orderForm: OrderForm) => {
102
79
  return orderForm.items.length !== 0
103
80
  }
104
81
 
105
- // Validate if the deliveryChannel from the session is different from the selected delivery channel
106
- // and if so needs to validate if the deliveryChannel for the session is available inside the slas for the item
107
- const shouldUpdateDeliveryChannel = (
82
+ const shouldUpdateDeliveryInfo = (
108
83
  logisticsInfo: LogisticsInfo[],
109
- session: IStoreSession | null | undefined
84
+ session: IStoreSession | null
110
85
  ) => {
111
- if (!session?.deliveryMode?.deliveryChannel) {
112
- return false
113
- }
114
- const { deliveryChannel } = session.deliveryMode
115
- for (const item of logisticsInfo) {
116
- if (item.selectedDeliveryChannel !== deliveryChannel) {
117
- const matchingSla = item.slas.find(
118
- (sla) => sla.deliveryChannel === deliveryChannel
119
- )
120
- if (matchingSla) {
121
- return true
122
- }
86
+ const deliveryChannel = session?.deliveryMode?.deliveryChannel
87
+ const deliveryMethod = session?.deliveryMode?.deliveryMethod
88
+ const { startDate, endDate } = session?.deliveryMode?.deliveryWindow || {}
89
+
90
+ return logisticsInfo.some(
91
+ ({ selectedDeliveryChannel, selectedSla, slas }) => {
92
+ const checkDeliveryChannel =
93
+ deliveryChannel && selectedDeliveryChannel !== deliveryChannel
94
+ const checkDeliveryMethod =
95
+ deliveryMethod && selectedSla !== deliveryMethod
96
+
97
+ return slas?.some((sla) => {
98
+ if (
99
+ (checkDeliveryChannel && sla.deliveryChannel === deliveryChannel) ||
100
+ (checkDeliveryMethod && sla.id === deliveryMethod)
101
+ ) {
102
+ return true
103
+ }
104
+ return (
105
+ startDate &&
106
+ endDate &&
107
+ sla.deliveryChannel === deliveryChannel &&
108
+ sla.id === deliveryMethod &&
109
+ (!sla?.deliveryWindow ||
110
+ sla?.deliveryWindow?.startDateUtc !== startDate ||
111
+ sla?.deliveryWindow?.endDateUtc !== endDate) &&
112
+ sla.availableDeliveryWindows?.some(
113
+ (window) =>
114
+ window?.startDateUtc === startDate &&
115
+ window?.endDateUtc === endDate
116
+ )
117
+ )
118
+ })
123
119
  }
124
- }
125
- return false
126
- }
127
-
128
- // Validate if the deliveryMethod from the session is different from the selectedSLA
129
- // and if so needs to validate if the deliveryMethod for the session is available inside the slas for the item
130
- const shouldUpdateDeliveryMethod = (
131
- logisticsInfo: LogisticsInfo[],
132
- session: IStoreSession
133
- ) => {
134
- if (!session?.deliveryMode?.deliveryMethod) {
135
- return false
136
- }
137
- const { deliveryMethod } = session.deliveryMode
138
- for (const item of logisticsInfo) {
139
- if (item.selectedSla !== deliveryMethod) {
140
- const matchingSla = item.slas.find((sla) => sla.id === deliveryMethod)
141
- if (matchingSla) {
142
- return true
143
- }
144
- }
145
- }
146
- return false
147
- }
148
-
149
- // Validate if the deliveryWindow from the session is different from the deliveryWindow of the SLA
150
- // and if so needs to validate if the deliveryWindow for the session is available inside the availableDeliveryWindows for the item
151
- const shouldUpdateDeliveryWindow = (
152
- logisticsInfo: LogisticsInfo[],
153
- session: IStoreSession
154
- ) => {
155
- if (
156
- !session?.deliveryMode?.deliveryWindow?.startDate ||
157
- !session?.deliveryMode?.deliveryWindow?.endDate
158
- ) {
159
- return false
160
- }
161
- const { startDate, endDate } = session.deliveryMode.deliveryWindow
162
- for (const item of logisticsInfo) {
163
- for (const sla of item.slas) {
164
- const matchingWindow = sla.availableDeliveryWindows?.some(
165
- (window) =>
166
- window.startDateUtc === startDate && window.endDateUtc === endDate
167
- )
168
- if (matchingWindow) {
169
- return true
170
- }
171
- }
172
- }
173
- return false
120
+ )
174
121
  }