@labdigital/commercetools-mock 2.46.0 → 2.47.1
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.cjs +589 -267
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +782 -58
- package/dist/index.d.ts +782 -58
- package/dist/index.js +574 -252
- package/dist/index.js.map +1 -1
- package/package.json +45 -53
- package/src/ctMock.ts +16 -15
- package/src/index.test.ts +5 -5
- package/src/lib/predicateParser.test.ts +62 -62
- package/src/lib/predicateParser.ts +32 -42
- package/src/lib/productSearchFilter.test.ts +18 -0
- package/src/lib/productSearchFilter.ts +7 -0
- package/src/lib/projectionSearchFilter.test.ts +17 -17
- package/src/lib/projectionSearchFilter.ts +2 -3
- package/src/oauth/server.test.ts +9 -1
- package/src/oauth/server.ts +26 -22
- package/src/priceSelector.ts +1 -1
- package/src/product-projection-search.ts +18 -19
- package/src/repositories/business-unit.ts +17 -16
- package/src/repositories/cart/actions.ts +32 -32
- package/src/repositories/cart/helpers.ts +1 -1
- package/src/repositories/cart/index.ts +8 -8
- package/src/repositories/cart-discount/actions.ts +1 -4
- package/src/repositories/category/actions.ts +2 -6
- package/src/repositories/custom-object.ts +20 -21
- package/src/repositories/customer/actions.ts +4 -4
- package/src/repositories/errors.ts +1 -1
- package/src/repositories/extension.ts +2 -1
- package/src/repositories/helpers.ts +27 -27
- package/src/repositories/index.ts +17 -17
- package/src/repositories/my-customer.ts +1 -1
- package/src/repositories/my-order.ts +2 -2
- package/src/repositories/order/index.ts +1 -1
- package/src/repositories/product/actions.ts +1 -1
- package/src/repositories/quote/actions.ts +83 -0
- package/src/repositories/quote/index.ts +54 -0
- package/src/repositories/quote-request/actions.ts +84 -0
- package/src/repositories/quote-request/index.test.ts +167 -0
- package/src/repositories/quote-request/index.ts +67 -0
- package/src/repositories/quote-staged/actions.ts +84 -0
- package/src/repositories/quote-staged/index.ts +47 -0
- package/src/repositories/review.ts +4 -4
- package/src/repositories/shipping-method/actions.ts +17 -17
- package/src/repositories/shipping-method/index.ts +6 -6
- package/src/repositories/shopping-list/actions.ts +1 -1
- package/src/repositories/shopping-list/index.ts +9 -1
- package/src/repositories/subscription.ts +2 -4
- package/src/server.ts +3 -2
- package/src/services/abstract.ts +32 -22
- package/src/services/as-associate-order.test.ts +1 -1
- package/src/services/cart-discount.test.ts +1 -1
- package/src/services/cart.test.ts +15 -15
- package/src/services/cart.ts +3 -2
- package/src/services/category.test.ts +1 -1
- package/src/services/custom-object.ts +8 -6
- package/src/services/customer.test.ts +4 -4
- package/src/services/customer.ts +5 -5
- package/src/services/index.ts +20 -14
- package/src/services/inventory-entry.test.ts +5 -5
- package/src/services/my-cart.test.ts +2 -2
- package/src/services/my-cart.ts +3 -2
- package/src/services/my-customer.test.ts +2 -2
- package/src/services/my-customer.ts +16 -12
- package/src/services/order.test.ts +8 -8
- package/src/services/order.ts +4 -3
- package/src/services/product-projection.test.ts +5 -5
- package/src/services/product-projection.ts +14 -16
- package/src/services/product.test.ts +1 -1
- package/src/services/product.ts +1 -1
- package/src/services/project.ts +4 -3
- package/src/services/quote-request.test.ts +59 -0
- package/src/services/quote-request.ts +16 -0
- package/src/services/quote-staged.ts +16 -0
- package/src/services/quote.ts +16 -0
- package/src/services/shipping-method.ts +4 -2
- package/src/services/standalone-price.test.ts +4 -4
- package/src/services/state.test.ts +1 -1
- package/src/services/store.test.ts +2 -2
- package/src/services/tax-category.test.ts +1 -1
- package/src/shipping.ts +3 -3
- package/src/storage/in-memory.ts +55 -63
- package/src/testing/customer.ts +1 -1
- package/src/types.ts +51 -31
- package/src/repositories/quote-request.ts +0 -17
- package/src/repositories/quote.ts +0 -14
- package/src/repositories/staged-quote.ts +0 -17
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* See https://docs.commercetools.com/api/predicates/query
|
|
6
6
|
*/
|
|
7
7
|
import { haversineDistance } from "./haversine";
|
|
8
|
-
import { Lexer, Parser
|
|
8
|
+
import { type ITokenPosition, Lexer, Parser } from "./parser";
|
|
9
9
|
|
|
10
10
|
export class PredicateError {
|
|
11
11
|
message: string;
|
|
@@ -34,10 +34,9 @@ export const matchesPredicate = (
|
|
|
34
34
|
const func = generateMatchFunc(item);
|
|
35
35
|
return func(target, variables ?? {});
|
|
36
36
|
});
|
|
37
|
-
} else {
|
|
38
|
-
const func = generateMatchFunc(predicate);
|
|
39
|
-
return func(target, variables ?? {});
|
|
40
37
|
}
|
|
38
|
+
const func = generateMatchFunc(predicate);
|
|
39
|
+
return func(target, variables ?? {});
|
|
41
40
|
};
|
|
42
41
|
|
|
43
42
|
export const parseQueryExpression = (
|
|
@@ -47,9 +46,8 @@ export const parseQueryExpression = (
|
|
|
47
46
|
const callbacks = predicate.map((item) => generateMatchFunc(item));
|
|
48
47
|
return (target: any, variables: VariableMap) =>
|
|
49
48
|
callbacks.every((callback) => callback(target, variables));
|
|
50
|
-
} else {
|
|
51
|
-
return generateMatchFunc(predicate);
|
|
52
49
|
}
|
|
50
|
+
return generateMatchFunc(predicate);
|
|
53
51
|
};
|
|
54
52
|
|
|
55
53
|
type TypeSymbol = {
|
|
@@ -177,7 +175,7 @@ const generateMatchFunc = (predicate: string): MatchFunc => {
|
|
|
177
175
|
(t) =>
|
|
178
176
|
({
|
|
179
177
|
type: "boolean",
|
|
180
|
-
value: t.token.match === "true"
|
|
178
|
+
value: t.token.match === "true",
|
|
181
179
|
pos: t.token.strpos(),
|
|
182
180
|
}) as TypeSymbol,
|
|
183
181
|
)
|
|
@@ -209,7 +207,7 @@ const generateMatchFunc = (predicate: string): MatchFunc => {
|
|
|
209
207
|
(t) =>
|
|
210
208
|
({
|
|
211
209
|
type: "int",
|
|
212
|
-
value: parseInt(t.token.match, 10),
|
|
210
|
+
value: Number.parseInt(t.token.match, 10),
|
|
213
211
|
pos: t.token.strpos(),
|
|
214
212
|
}) as TypeSymbol,
|
|
215
213
|
)
|
|
@@ -219,7 +217,7 @@ const generateMatchFunc = (predicate: string): MatchFunc => {
|
|
|
219
217
|
(t) =>
|
|
220
218
|
({
|
|
221
219
|
type: "float",
|
|
222
|
-
value: parseFloat(t.token.match),
|
|
220
|
+
value: Number.parseFloat(t.token.match),
|
|
223
221
|
pos: t.token.strpos(),
|
|
224
222
|
}) as TypeSymbol,
|
|
225
223
|
)
|
|
@@ -242,9 +240,8 @@ const generateMatchFunc = (predicate: string): MatchFunc => {
|
|
|
242
240
|
const expr: any = parser.parse({ terminals: [bp - 1] });
|
|
243
241
|
if (Array.isArray(expr)) {
|
|
244
242
|
return [left, ...expr];
|
|
245
|
-
} else {
|
|
246
|
-
return [left, expr];
|
|
247
243
|
}
|
|
244
|
+
return [left, expr];
|
|
248
245
|
})
|
|
249
246
|
.nud("(", 100, (t) => {
|
|
250
247
|
const expr: any = parser.parse({ terminals: [")"] });
|
|
@@ -262,17 +259,16 @@ const generateMatchFunc = (predicate: string): MatchFunc => {
|
|
|
262
259
|
}
|
|
263
260
|
return false;
|
|
264
261
|
});
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
return expr(value, vars);
|
|
262
|
+
}
|
|
263
|
+
const value = resolveValue(obj, left);
|
|
264
|
+
if (value) {
|
|
265
|
+
if (Array.isArray(value)) {
|
|
266
|
+
return value.some((item) => expr(item, vars));
|
|
273
267
|
}
|
|
274
|
-
|
|
268
|
+
|
|
269
|
+
return expr(value, vars);
|
|
275
270
|
}
|
|
271
|
+
return false;
|
|
276
272
|
};
|
|
277
273
|
})
|
|
278
274
|
.bp(")", 0)
|
|
@@ -290,14 +286,13 @@ const generateMatchFunc = (predicate: string): MatchFunc => {
|
|
|
290
286
|
}
|
|
291
287
|
return value === other;
|
|
292
288
|
});
|
|
293
|
-
} else {
|
|
294
|
-
const resolvedValue = resolveValue(obj, left);
|
|
295
|
-
const resolvedSymbol = resolveSymbol(expr, vars);
|
|
296
|
-
if (Array.isArray(resolvedValue)) {
|
|
297
|
-
return !!resolvedValue.some((elem) => elem === resolvedSymbol);
|
|
298
|
-
}
|
|
299
|
-
return resolvedValue === resolvedSymbol;
|
|
300
289
|
}
|
|
290
|
+
const resolvedValue = resolveValue(obj, left);
|
|
291
|
+
const resolvedSymbol = resolveSymbol(expr, vars);
|
|
292
|
+
if (Array.isArray(resolvedValue)) {
|
|
293
|
+
return !!resolvedValue.some((elem) => elem === resolvedSymbol);
|
|
294
|
+
}
|
|
295
|
+
return resolvedValue === resolvedSymbol;
|
|
301
296
|
};
|
|
302
297
|
})
|
|
303
298
|
.led("!=", 20, ({ left, bp }) => {
|
|
@@ -353,12 +348,11 @@ const generateMatchFunc = (predicate: string): MatchFunc => {
|
|
|
353
348
|
const val = resolveValue(obj, left);
|
|
354
349
|
return val.length === 0;
|
|
355
350
|
};
|
|
356
|
-
} else {
|
|
357
|
-
return (obj: any, vars: VariableMap) => {
|
|
358
|
-
const val = resolveValue(obj, left);
|
|
359
|
-
return val.length !== 0;
|
|
360
|
-
};
|
|
361
351
|
}
|
|
352
|
+
return (obj: any, vars: VariableMap) => {
|
|
353
|
+
const val = resolveValue(obj, left);
|
|
354
|
+
return val.length !== 0;
|
|
355
|
+
};
|
|
362
356
|
}
|
|
363
357
|
case "defined": {
|
|
364
358
|
if (!invert) {
|
|
@@ -366,12 +360,11 @@ const generateMatchFunc = (predicate: string): MatchFunc => {
|
|
|
366
360
|
const val = resolveValue(obj, left);
|
|
367
361
|
return val !== undefined;
|
|
368
362
|
};
|
|
369
|
-
} else {
|
|
370
|
-
return (obj: any, vars: VariableMap) => {
|
|
371
|
-
const val = resolveValue(obj, left);
|
|
372
|
-
return val === undefined;
|
|
373
|
-
};
|
|
374
363
|
}
|
|
364
|
+
return (obj: any, vars: VariableMap) => {
|
|
365
|
+
const val = resolveValue(obj, left);
|
|
366
|
+
return val === undefined;
|
|
367
|
+
};
|
|
375
368
|
}
|
|
376
369
|
default: {
|
|
377
370
|
throw new Error("Unexpected");
|
|
@@ -463,9 +456,8 @@ const generateMatchFunc = (predicate: string): MatchFunc => {
|
|
|
463
456
|
const array = expr.map((item: TypeSymbol) => resolveSymbol(item, vars));
|
|
464
457
|
if (keyword.type === "ALL") {
|
|
465
458
|
return array.every((item: any) => value.includes(item));
|
|
466
|
-
} else {
|
|
467
|
-
return array.some((item: any) => value.includes(item));
|
|
468
459
|
}
|
|
460
|
+
return array.some((item: any) => value.includes(item));
|
|
469
461
|
};
|
|
470
462
|
})
|
|
471
463
|
|
|
@@ -478,9 +470,7 @@ const generateMatchFunc = (predicate: string): MatchFunc => {
|
|
|
478
470
|
const column = lines[lines.length - 1].length;
|
|
479
471
|
|
|
480
472
|
throw new PredicateError(
|
|
481
|
-
`Unexpected end of input, expected SphereIdentifierChar, comparison
|
|
482
|
-
`operator, not, in, contains, is, within or matches` +
|
|
483
|
-
` (line ${lines.length}, column ${column})`,
|
|
473
|
+
`Unexpected end of input, expected SphereIdentifierChar, comparison operator, not, in, contains, is, within or matches (line ${lines.length}, column ${column})`,
|
|
484
474
|
);
|
|
485
475
|
}
|
|
486
476
|
return result;
|
|
@@ -138,6 +138,24 @@ describe("Product search filter", () => {
|
|
|
138
138
|
},
|
|
139
139
|
}).isMatch,
|
|
140
140
|
).toBeTruthy();
|
|
141
|
+
|
|
142
|
+
expect(
|
|
143
|
+
match({
|
|
144
|
+
exact: {
|
|
145
|
+
field: "variants.sku",
|
|
146
|
+
values: ["MYSKU", "OTHER"],
|
|
147
|
+
},
|
|
148
|
+
}).isMatch,
|
|
149
|
+
).toBeTruthy();
|
|
150
|
+
|
|
151
|
+
expect(
|
|
152
|
+
match({
|
|
153
|
+
exact: {
|
|
154
|
+
field: "variants.sku",
|
|
155
|
+
values: ["OTHER"],
|
|
156
|
+
},
|
|
157
|
+
}).isMatch,
|
|
158
|
+
).toBeFalsy();
|
|
141
159
|
});
|
|
142
160
|
|
|
143
161
|
test("by attribute value", async () => {
|
|
@@ -98,6 +98,13 @@ export const parseSearchQuery = (
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
if (isSearchExactExpression(searchQuery)) {
|
|
101
|
+
if (Array.isArray(searchQuery.exact.values)) {
|
|
102
|
+
return generateFieldMatchFunc(
|
|
103
|
+
(value: any) => (searchQuery.exact.values ?? []).includes(value),
|
|
104
|
+
searchQuery.exact,
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
101
108
|
return generateFieldMatchFunc(
|
|
102
109
|
(value: any) => value === searchQuery.exact.value,
|
|
103
110
|
searchQuery.exact,
|
|
@@ -68,8 +68,8 @@ describe("Search filter", () => {
|
|
|
68
68
|
};
|
|
69
69
|
|
|
70
70
|
test("by product key", async () => {
|
|
71
|
-
expect(match(
|
|
72
|
-
expect(match(
|
|
71
|
+
expect(match("key:exists").isMatch).toBeTruthy();
|
|
72
|
+
expect(match("key:missing").isMatch).toBeFalsy();
|
|
73
73
|
expect(match(`key:"test-product"`).isMatch).toBeTruthy();
|
|
74
74
|
});
|
|
75
75
|
|
|
@@ -80,29 +80,29 @@ describe("Search filter", () => {
|
|
|
80
80
|
});
|
|
81
81
|
|
|
82
82
|
test("by SKU", async () => {
|
|
83
|
-
expect(match(
|
|
84
|
-
expect(match(
|
|
83
|
+
expect(match("variants.sku:exists").isMatch).toBeTruthy();
|
|
84
|
+
expect(match("variants.sku:missing").isMatch).toBeFalsy();
|
|
85
85
|
expect(match(`variants.sku:"MYSKU"`).isMatch).toBeTruthy();
|
|
86
86
|
});
|
|
87
87
|
|
|
88
88
|
test("by attribute value", async () => {
|
|
89
|
-
expect(match(
|
|
90
|
-
expect(match(
|
|
91
|
-
expect(match(
|
|
92
|
-
expect(match(
|
|
89
|
+
expect(match("variants.attributes.number:4").isMatch).toBeTruthy();
|
|
90
|
+
expect(match("variants.attributes.number:3,4").isMatch).toBeTruthy();
|
|
91
|
+
expect(match("variants.attributes.number:3,4,5").isMatch).toBeTruthy();
|
|
92
|
+
expect(match("variants.attributes.number:1,2,3,5").isMatch).toBeFalsy();
|
|
93
93
|
});
|
|
94
94
|
|
|
95
95
|
test("by attribute range", async () => {
|
|
96
96
|
expect(
|
|
97
|
-
match(
|
|
97
|
+
match("variants.attributes.number:range (0 TO 5)").isMatch,
|
|
98
98
|
).toBeTruthy();
|
|
99
99
|
|
|
100
100
|
expect(
|
|
101
|
-
match(
|
|
101
|
+
match("variants.attributes.number:range (* TO 5)").isMatch,
|
|
102
102
|
).toBeTruthy();
|
|
103
103
|
|
|
104
104
|
expect(
|
|
105
|
-
match(
|
|
105
|
+
match("variants.attributes.number:range (* TO *)").isMatch,
|
|
106
106
|
).toBeTruthy();
|
|
107
107
|
});
|
|
108
108
|
|
|
@@ -118,14 +118,14 @@ describe("Search filter", () => {
|
|
|
118
118
|
|
|
119
119
|
test("by price range", async () => {
|
|
120
120
|
expect(
|
|
121
|
-
match(
|
|
121
|
+
match("variants.price.centAmount:range (1500 TO 2000)").isMatch,
|
|
122
122
|
).toBeTruthy();
|
|
123
123
|
});
|
|
124
124
|
|
|
125
125
|
test("by price range - or", async () => {
|
|
126
126
|
expect(
|
|
127
127
|
match(
|
|
128
|
-
|
|
128
|
+
"variants.price.centAmount:range (2 TO 1500 ), (1500 TO 3000), (3000 TO 6000)",
|
|
129
129
|
).isMatch,
|
|
130
130
|
).toBeTruthy();
|
|
131
131
|
});
|
|
@@ -136,7 +136,7 @@ describe("Search filter", () => {
|
|
|
136
136
|
|
|
137
137
|
// No currency given
|
|
138
138
|
result = match(
|
|
139
|
-
|
|
139
|
+
"variants.scopedPrice.value.centAmount:range (1500 TO 2000)",
|
|
140
140
|
);
|
|
141
141
|
expect(result.isMatch).toBeFalsy();
|
|
142
142
|
|
|
@@ -145,7 +145,7 @@ describe("Search filter", () => {
|
|
|
145
145
|
applyPriceSelector(products, { currency: "EUR" });
|
|
146
146
|
|
|
147
147
|
result = match(
|
|
148
|
-
|
|
148
|
+
"variants.scopedPrice.value.centAmount:range (1500 TO 2000)",
|
|
149
149
|
products[0],
|
|
150
150
|
);
|
|
151
151
|
expect(result.isMatch).toBeTruthy();
|
|
@@ -161,7 +161,7 @@ describe("Search filter", () => {
|
|
|
161
161
|
applyPriceSelector(products, { currency: "USD" });
|
|
162
162
|
|
|
163
163
|
result = match(
|
|
164
|
-
|
|
164
|
+
"variants.scopedPrice.value.centAmount:range (1500 TO 2000)",
|
|
165
165
|
products[0],
|
|
166
166
|
);
|
|
167
167
|
expect(result.isMatch).toBeFalsy();
|
|
@@ -170,7 +170,7 @@ describe("Search filter", () => {
|
|
|
170
170
|
products = [cloneObject(exampleProduct)];
|
|
171
171
|
applyPriceSelector(products, { currency: "EUR", country: "NL" });
|
|
172
172
|
result = match(
|
|
173
|
-
|
|
173
|
+
"variants.scopedPrice.value.centAmount:range (1500 TO 2000)",
|
|
174
174
|
products[0],
|
|
175
175
|
);
|
|
176
176
|
expect(result.isMatch).toBeFalsy();
|
|
@@ -154,7 +154,7 @@ const parseFilter = (filter: string): ExpressionSet => {
|
|
|
154
154
|
({
|
|
155
155
|
type: "Symbol",
|
|
156
156
|
kind: "int",
|
|
157
|
-
value: parseInt(t.token.match, 10),
|
|
157
|
+
value: Number.parseInt(t.token.match, 10),
|
|
158
158
|
}) as TypeSymbol,
|
|
159
159
|
)
|
|
160
160
|
.nud("STAR", 5, (_) => ({
|
|
@@ -184,9 +184,8 @@ const parseFilter = (filter: string): ExpressionSet => {
|
|
|
184
184
|
const expr: any = parser.parse({ terminals: [bp - 1] });
|
|
185
185
|
if (Array.isArray(expr)) {
|
|
186
186
|
return [left, ...expr];
|
|
187
|
-
} else {
|
|
188
|
-
return [left, expr];
|
|
189
187
|
}
|
|
188
|
+
return [left, expr];
|
|
190
189
|
})
|
|
191
190
|
.nud("(", 100, (t) => {
|
|
192
191
|
const expr: any = parser.parse({ terminals: [")"] });
|
package/src/oauth/server.test.ts
CHANGED
|
@@ -39,6 +39,14 @@ describe("OAuth2Server", () => {
|
|
|
39
39
|
|
|
40
40
|
expect(response.status, JSON.stringify(body)).toBe(200);
|
|
41
41
|
expect(body).toHaveProperty("access_token");
|
|
42
|
+
expect(body).toEqual({
|
|
43
|
+
// scope: expect.stringMatching(/anonymous_id:([^\s]+)/),
|
|
44
|
+
scope: expect.any(String),
|
|
45
|
+
access_token: expect.stringMatching(/\S{8,}==$/),
|
|
46
|
+
refresh_token: expect.stringMatching(/my-project.*/),
|
|
47
|
+
expires_in: 172800,
|
|
48
|
+
token_type: "Bearer",
|
|
49
|
+
});
|
|
42
50
|
});
|
|
43
51
|
|
|
44
52
|
it("should failed on invalid refresh token", async () => {
|
|
@@ -55,7 +63,7 @@ describe("OAuth2Server", () => {
|
|
|
55
63
|
|
|
56
64
|
it("should refresh a token", async () => {
|
|
57
65
|
const createResponse = await supertest(app)
|
|
58
|
-
.post(
|
|
66
|
+
.post("/my-project/anonymous/token")
|
|
59
67
|
.auth("validClientId", "validClientSecret")
|
|
60
68
|
.query({ grant_type: "client_credentials" })
|
|
61
69
|
.send();
|
package/src/oauth/server.ts
CHANGED
|
@@ -160,7 +160,7 @@ export class OAuth2Server {
|
|
|
160
160
|
);
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
const grantType = request.query.grant_type || request.body
|
|
163
|
+
const grantType = request.query.grant_type || request.body?.grant_type;
|
|
164
164
|
if (!grantType) {
|
|
165
165
|
return next(
|
|
166
166
|
new CommercetoolsError<InvalidRequestError>(
|
|
@@ -179,10 +179,12 @@ export class OAuth2Server {
|
|
|
179
179
|
request.credentials.clientSecret,
|
|
180
180
|
request.query.scope?.toString(),
|
|
181
181
|
);
|
|
182
|
-
|
|
183
|
-
|
|
182
|
+
response.status(200).send(token);
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
if (grantType === "refresh_token") {
|
|
184
186
|
const refreshToken =
|
|
185
|
-
request.query.refresh_token?.toString() || request.body
|
|
187
|
+
request.query.refresh_token?.toString() || request.body?.refresh_token;
|
|
186
188
|
if (!refreshToken) {
|
|
187
189
|
return next(
|
|
188
190
|
new CommercetoolsError<InvalidRequestError>(
|
|
@@ -213,18 +215,18 @@ export class OAuth2Server {
|
|
|
213
215
|
),
|
|
214
216
|
);
|
|
215
217
|
}
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
return next(
|
|
219
|
-
new CommercetoolsError<UnsupportedGrantType>(
|
|
220
|
-
{
|
|
221
|
-
code: "unsupported_grant_type",
|
|
222
|
-
message: `Invalid parameter: grant_type: Invalid grant type: ${grantType}`,
|
|
223
|
-
},
|
|
224
|
-
400,
|
|
225
|
-
),
|
|
226
|
-
);
|
|
218
|
+
response.status(200).send(token);
|
|
219
|
+
return;
|
|
227
220
|
}
|
|
221
|
+
return next(
|
|
222
|
+
new CommercetoolsError<UnsupportedGrantType>(
|
|
223
|
+
{
|
|
224
|
+
code: "unsupported_grant_type",
|
|
225
|
+
message: `Invalid parameter: grant_type: Invalid grant type: ${grantType}`,
|
|
226
|
+
},
|
|
227
|
+
400,
|
|
228
|
+
),
|
|
229
|
+
);
|
|
228
230
|
}
|
|
229
231
|
|
|
230
232
|
async customerTokenHandler(
|
|
@@ -233,7 +235,7 @@ export class OAuth2Server {
|
|
|
233
235
|
next: NextFunction,
|
|
234
236
|
) {
|
|
235
237
|
const projectKey = request.params.projectKey;
|
|
236
|
-
const grantType = request.query.grant_type || request.body
|
|
238
|
+
const grantType = request.query.grant_type || request.body?.grant_type;
|
|
237
239
|
if (!grantType) {
|
|
238
240
|
return next(
|
|
239
241
|
new CommercetoolsError<InvalidRequestError>(
|
|
@@ -247,12 +249,12 @@ export class OAuth2Server {
|
|
|
247
249
|
}
|
|
248
250
|
|
|
249
251
|
if (grantType === "password") {
|
|
250
|
-
const username = request.query.username || request.body
|
|
252
|
+
const username = request.query.username || request.body?.username;
|
|
251
253
|
const password = hashPassword(
|
|
252
254
|
request.query.password || request.body.password,
|
|
253
255
|
);
|
|
254
256
|
const scope =
|
|
255
|
-
request.query.scope?.toString() || request.body
|
|
257
|
+
request.query.scope?.toString() || request.body?.scope?.toString();
|
|
256
258
|
|
|
257
259
|
const result = this.customerRepository.query(
|
|
258
260
|
{ projectKey: request.params.projectKey },
|
|
@@ -275,7 +277,7 @@ export class OAuth2Server {
|
|
|
275
277
|
|
|
276
278
|
const customer = result.results[0];
|
|
277
279
|
const token = this.store.getCustomerToken(projectKey, customer.id, scope);
|
|
278
|
-
|
|
280
|
+
response.status(200).send(token);
|
|
279
281
|
}
|
|
280
282
|
}
|
|
281
283
|
|
|
@@ -328,7 +330,8 @@ export class OAuth2Server {
|
|
|
328
330
|
|
|
329
331
|
const customer = result.results[0];
|
|
330
332
|
const token = this.store.getCustomerToken(projectKey, customer.id, scope);
|
|
331
|
-
|
|
333
|
+
response.status(200).send(token);
|
|
334
|
+
return;
|
|
332
335
|
}
|
|
333
336
|
}
|
|
334
337
|
|
|
@@ -353,7 +356,7 @@ export class OAuth2Server {
|
|
|
353
356
|
|
|
354
357
|
if (grantType === "client_credentials") {
|
|
355
358
|
const scope =
|
|
356
|
-
request.query.scope?.toString() || request.body
|
|
359
|
+
request.query.scope?.toString() || request.body?.scope?.toString();
|
|
357
360
|
|
|
358
361
|
const anonymous_id = undefined;
|
|
359
362
|
|
|
@@ -362,7 +365,8 @@ export class OAuth2Server {
|
|
|
362
365
|
anonymous_id,
|
|
363
366
|
scope,
|
|
364
367
|
);
|
|
365
|
-
|
|
368
|
+
response.status(200).send(token);
|
|
369
|
+
return;
|
|
366
370
|
}
|
|
367
371
|
}
|
|
368
372
|
}
|
package/src/priceSelector.ts
CHANGED
|
@@ -27,25 +27,25 @@ import type { AbstractStorage } from "./storage";
|
|
|
27
27
|
import type { Writable } from "./types";
|
|
28
28
|
|
|
29
29
|
export type ProductProjectionSearchParams = {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
fuzzy?: boolean;
|
|
31
|
+
fuzzyLevel?: number;
|
|
32
|
+
markMatchingVariants?: boolean;
|
|
33
|
+
staged?: boolean;
|
|
34
|
+
filter?: string[];
|
|
35
35
|
"filter.facets"?: string[];
|
|
36
36
|
"filter.query"?: string[];
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
37
|
+
facet?: string | string[];
|
|
38
|
+
sort?: string | string[];
|
|
39
|
+
limit?: number;
|
|
40
|
+
offset?: number;
|
|
41
|
+
withTotal?: boolean;
|
|
42
|
+
priceCurrency?: string;
|
|
43
|
+
priceCountry?: string;
|
|
44
|
+
priceCustomerGroup?: string;
|
|
45
|
+
priceChannel?: string;
|
|
46
|
+
localeProjection?: string;
|
|
47
|
+
storeProjection?: string;
|
|
48
|
+
expand?: string | string[];
|
|
49
49
|
[key: string]: QueryParam;
|
|
50
50
|
};
|
|
51
51
|
|
|
@@ -342,9 +342,8 @@ export class ProductProjectionSearch {
|
|
|
342
342
|
max: numValues > 0 ? Math.max(...values) : 0,
|
|
343
343
|
mean: numValues > 0 ? mean(values) : 0,
|
|
344
344
|
};
|
|
345
|
-
} else {
|
|
346
|
-
throw new Error("not supported");
|
|
347
345
|
}
|
|
346
|
+
throw new Error("not supported");
|
|
348
347
|
}) || [];
|
|
349
348
|
const data: RangeFacetResult = {
|
|
350
349
|
type: "range",
|
|
@@ -7,21 +7,21 @@ import type {
|
|
|
7
7
|
CompanyDraft,
|
|
8
8
|
DivisionDraft,
|
|
9
9
|
} from "@commercetools/platform-sdk";
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
10
|
+
import type {
|
|
11
|
+
Associate,
|
|
12
|
+
BusinessUnit,
|
|
13
|
+
BusinessUnitAddAddressAction,
|
|
14
|
+
BusinessUnitAddAssociateAction,
|
|
15
|
+
BusinessUnitAddStoreAction,
|
|
16
|
+
BusinessUnitChangeAddressAction,
|
|
17
|
+
BusinessUnitChangeNameAction,
|
|
18
|
+
BusinessUnitChangeParentUnitAction,
|
|
19
|
+
BusinessUnitDraft,
|
|
20
|
+
BusinessUnitSetAssociatesAction,
|
|
21
|
+
BusinessUnitSetContactEmailAction,
|
|
22
|
+
BusinessUnitSetStoreModeAction,
|
|
23
|
+
Company,
|
|
24
|
+
Division,
|
|
25
25
|
} from "@commercetools/platform-sdk";
|
|
26
26
|
import type { Config } from "~src/config";
|
|
27
27
|
import { generateRandomString, getBaseResourceProperties } from "../helpers";
|
|
@@ -110,7 +110,8 @@ export class BusinessUnitRepository extends AbstractResourceRepository<"business
|
|
|
110
110
|
|
|
111
111
|
this.saveNew(context, division);
|
|
112
112
|
return division;
|
|
113
|
-
}
|
|
113
|
+
}
|
|
114
|
+
if (this._isCompanyDraft(draft)) {
|
|
114
115
|
const company = resource as Company;
|
|
115
116
|
|
|
116
117
|
this.saveNew(context, company);
|
|
@@ -7,36 +7,36 @@ import type {
|
|
|
7
7
|
MissingTaxRateForCountryError,
|
|
8
8
|
ShippingMethodDoesNotMatchCartError,
|
|
9
9
|
} from "@commercetools/platform-sdk";
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
10
|
+
import type {
|
|
11
|
+
Address,
|
|
12
|
+
AddressDraft,
|
|
13
|
+
Cart,
|
|
14
|
+
CartAddItemShippingAddressAction,
|
|
15
|
+
CartAddLineItemAction,
|
|
16
|
+
CartChangeLineItemQuantityAction,
|
|
17
|
+
CartChangeTaxRoundingModeAction,
|
|
18
|
+
CartRemoveDiscountCodeAction,
|
|
19
|
+
CartRemoveLineItemAction,
|
|
20
|
+
CartSetBillingAddressAction,
|
|
21
|
+
CartSetBillingAddressCustomTypeAction,
|
|
22
|
+
CartSetCountryAction,
|
|
23
|
+
CartSetCustomFieldAction,
|
|
24
|
+
CartSetCustomShippingMethodAction,
|
|
25
|
+
CartSetCustomTypeAction,
|
|
26
|
+
CartSetCustomerEmailAction,
|
|
27
|
+
CartSetDirectDiscountsAction,
|
|
28
|
+
CartSetLineItemShippingDetailsAction,
|
|
29
|
+
CartSetLocaleAction,
|
|
30
|
+
CartSetShippingAddressAction,
|
|
31
|
+
CartSetShippingAddressCustomTypeAction,
|
|
32
|
+
CartSetShippingMethodAction,
|
|
33
|
+
CustomFields,
|
|
34
|
+
GeneralError,
|
|
35
|
+
ItemShippingDetails,
|
|
36
|
+
LineItem,
|
|
37
|
+
Product,
|
|
38
|
+
ProductPagedQueryResponse,
|
|
39
|
+
ProductVariant,
|
|
40
40
|
} from "@commercetools/platform-sdk";
|
|
41
41
|
import type {
|
|
42
42
|
DirectDiscount,
|
|
@@ -232,7 +232,7 @@ export class CartUpdateHandler
|
|
|
232
232
|
} else {
|
|
233
233
|
throw new CommercetoolsError<GeneralError>({
|
|
234
234
|
code: "General",
|
|
235
|
-
message:
|
|
235
|
+
message: "Either lineItemid or lineItemKey needs to be provided.",
|
|
236
236
|
});
|
|
237
237
|
}
|
|
238
238
|
|
|
@@ -656,7 +656,7 @@ export class CartUpdateHandler
|
|
|
656
656
|
// Locations cannot be assigned to more than one zone.
|
|
657
657
|
// See https://docs.commercetools.com/api/projects/zones#location
|
|
658
658
|
const zoneRate = method.zoneRates.find((rate) =>
|
|
659
|
-
rate.zone.obj
|
|
659
|
+
rate.zone.obj?.locations.some((loc) => loc.country === country),
|
|
660
660
|
);
|
|
661
661
|
|
|
662
662
|
if (!zoneRate) {
|
|
@@ -24,7 +24,7 @@ export const selectPrice = ({
|
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
export const calculateLineItemTotalPrice = (lineItem: LineItem): number =>
|
|
27
|
-
lineItem.price
|
|
27
|
+
lineItem.price?.value.centAmount * lineItem.quantity;
|
|
28
28
|
|
|
29
29
|
export const calculateCartTotalPrice = (cart: Cart): number =>
|
|
30
30
|
cart.lineItems.reduce((cur, item) => cur + item.totalPrice.centAmount, 0);
|