@labdigital/commercetools-mock 2.66.0 → 3.0.0-beta.0
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/README.md +31 -8
- package/dist/abstract-BKFcva6S.mjs +1044 -0
- package/dist/abstract-BKFcva6S.mjs.map +1 -0
- package/dist/config-BcNSzPZz.d.mts +1718 -0
- package/dist/index.d.mts +50 -1633
- package/dist/index.mjs +3769 -2653
- package/dist/index.mjs.map +1 -1
- package/dist/storage/sqlite.d.mts +59 -0
- package/dist/storage/sqlite.mjs +234 -0
- package/dist/storage/sqlite.mjs.map +1 -0
- package/package.json +26 -29
- package/src/ctMock.ts +125 -136
- package/src/helpers.ts +14 -6
- package/src/index.ts +5 -0
- package/src/lib/masking.ts +4 -5
- package/src/lib/product-review-statistics.test.ts +257 -294
- package/src/lib/review-statistics.ts +17 -4
- package/src/oauth/helpers.ts +7 -4
- package/src/oauth/server.test.ts +102 -62
- package/src/oauth/server.ts +215 -213
- package/src/oauth/store.ts +20 -6
- package/src/orderSearch.ts +3 -3
- package/src/product-projection-search.ts +38 -20
- package/src/product-search-availability.test.ts +31 -52
- package/src/product-search.ts +19 -10
- package/src/projectAPI.ts +6 -22
- package/src/repositories/abstract.ts +182 -48
- package/src/repositories/as-associate.test.ts +19 -19
- package/src/repositories/associate-role.ts +12 -23
- package/src/repositories/attribute-group.test.ts +23 -23
- package/src/repositories/attribute-group.ts +6 -4
- package/src/repositories/business-unit.test.ts +63 -57
- package/src/repositories/business-unit.ts +107 -55
- package/src/repositories/cart/actions.ts +96 -65
- package/src/repositories/cart/helpers.ts +15 -11
- package/src/repositories/cart/index.test.ts +136 -30
- package/src/repositories/cart/index.ts +76 -59
- package/src/repositories/cart-discount/actions.ts +12 -44
- package/src/repositories/cart-discount/index.ts +20 -8
- package/src/repositories/category/actions.ts +27 -27
- package/src/repositories/category/index.test.ts +13 -9
- package/src/repositories/category/index.ts +40 -23
- package/src/repositories/channel.test.ts +53 -51
- package/src/repositories/channel.ts +12 -22
- package/src/repositories/custom-object.ts +34 -25
- package/src/repositories/customer/actions.ts +47 -25
- package/src/repositories/customer/index.test.ts +11 -11
- package/src/repositories/customer/index.ts +65 -35
- package/src/repositories/customer-group.test.ts +44 -42
- package/src/repositories/customer-group.ts +12 -22
- package/src/repositories/discount-code/actions.ts +3 -19
- package/src/repositories/discount-code/index.ts +9 -4
- package/src/repositories/discount-group/index.ts +8 -3
- package/src/repositories/extension.test.ts +27 -27
- package/src/repositories/extension.ts +10 -5
- package/src/repositories/helpers.ts +126 -47
- package/src/repositories/inventory-entry/actions.ts +3 -24
- package/src/repositories/inventory-entry/index.ts +19 -11
- package/src/repositories/my-customer.ts +13 -12
- package/src/repositories/my-order.ts +5 -2
- package/src/repositories/order/actions.ts +84 -56
- package/src/repositories/order/index.test.ts +36 -31
- package/src/repositories/order/index.ts +83 -49
- package/src/repositories/order-edit.ts +8 -3
- package/src/repositories/payment/actions.ts +64 -44
- package/src/repositories/payment/helpers.ts +3 -3
- package/src/repositories/payment/index.ts +28 -12
- package/src/repositories/product/actions.ts +133 -98
- package/src/repositories/product/helpers.ts +29 -16
- package/src/repositories/product/index.ts +42 -25
- package/src/repositories/product-discount.ts +6 -4
- package/src/repositories/product-projection.ts +41 -21
- package/src/repositories/product-selection.ts +8 -15
- package/src/repositories/product-tailoring.ts +22 -3
- package/src/repositories/product-type.ts +45 -4
- package/src/repositories/project.ts +57 -13
- package/src/repositories/quote/actions.ts +5 -28
- package/src/repositories/quote/index.ts +29 -6
- package/src/repositories/quote-request/actions.ts +5 -28
- package/src/repositories/quote-request/index.test.ts +3 -3
- package/src/repositories/quote-request/index.ts +31 -11
- package/src/repositories/quote-staged/actions.ts +5 -28
- package/src/repositories/quote-staged/index.ts +22 -8
- package/src/repositories/recurrence-policy/index.ts +6 -4
- package/src/repositories/recurring-order/actions.ts +7 -32
- package/src/repositories/recurring-order/index.ts +8 -6
- package/src/repositories/review.test.ts +147 -142
- package/src/repositories/review.ts +31 -37
- package/src/repositories/shipping-method/actions.ts +11 -28
- package/src/repositories/shipping-method/index.ts +26 -15
- package/src/repositories/shopping-list/actions.ts +21 -31
- package/src/repositories/shopping-list/index.ts +44 -22
- package/src/repositories/standalone-price.ts +6 -4
- package/src/repositories/state.ts +15 -9
- package/src/repositories/store.ts +21 -32
- package/src/repositories/subscription.test.ts +22 -22
- package/src/repositories/subscription.ts +8 -3
- package/src/repositories/tax-category/index.ts +8 -3
- package/src/repositories/type/actions.ts +21 -3
- package/src/repositories/type/index.ts +5 -3
- package/src/repositories/zone.test.ts +112 -77
- package/src/repositories/zone.ts +5 -3
- package/src/schemas/generated/associate-role.ts +13 -0
- package/src/schemas/generated/attribute-group.ts +12 -0
- package/src/schemas/generated/business-unit.ts +38 -0
- package/src/schemas/generated/cart-discount.ts +33 -0
- package/src/schemas/generated/cart.ts +61 -0
- package/src/schemas/generated/category.ts +25 -0
- package/src/schemas/generated/channel.ts +21 -0
- package/src/schemas/generated/common.ts +1372 -0
- package/src/schemas/generated/custom-object.ts +11 -0
- package/src/schemas/generated/customer-group.ts +11 -0
- package/src/schemas/generated/customer.ts +47 -0
- package/src/schemas/generated/discount-code.ts +25 -0
- package/src/schemas/generated/discount-group.ts +13 -0
- package/src/schemas/generated/extension.ts +15 -0
- package/src/schemas/generated/index.ts +42 -0
- package/src/schemas/generated/inventory-entry.ts +20 -0
- package/src/schemas/generated/my-quote-request.ts +10 -0
- package/src/schemas/generated/order-edit.ts +18 -0
- package/src/schemas/generated/order-from-cart.ts +25 -0
- package/src/schemas/generated/payment.ts +30 -0
- package/src/schemas/generated/product-discount.ts +20 -0
- package/src/schemas/generated/product-selection.ts +18 -0
- package/src/schemas/generated/product-tailoring.ts +26 -0
- package/src/schemas/generated/product-type.ts +12 -0
- package/src/schemas/generated/product.ts +37 -0
- package/src/schemas/generated/quote-request.ts +19 -0
- package/src/schemas/generated/quote.ts +18 -0
- package/src/schemas/generated/recurrence-policy.ts +15 -0
- package/src/schemas/generated/recurring-order.ts +19 -0
- package/src/schemas/generated/review.ts +24 -0
- package/src/schemas/generated/shipping-method.ts +24 -0
- package/src/schemas/generated/shopping-list.ts +28 -0
- package/src/schemas/generated/staged-quote.ts +18 -0
- package/src/schemas/generated/standalone-price.ts +32 -0
- package/src/schemas/generated/state.ts +20 -0
- package/src/schemas/generated/store.ts +23 -0
- package/src/schemas/generated/subscription.ts +20 -0
- package/src/schemas/generated/tax-category.ts +12 -0
- package/src/schemas/generated/type.ts +17 -0
- package/src/schemas/generated/zone.ts +12 -0
- package/src/schemas/update-request.ts +3 -5
- package/src/server.ts +32 -4
- package/src/services/abstract.ts +207 -101
- package/src/services/as-associate-cart.test.ts +28 -36
- package/src/services/as-associate-cart.ts +15 -12
- package/src/services/as-associate-order.test.ts +33 -40
- package/src/services/as-associate-order.ts +15 -12
- package/src/services/as-associate-quote-request.ts +15 -12
- package/src/services/as-associate-shopping-list.test.ts +25 -35
- package/src/services/as-associate-shopping-list.ts +15 -12
- package/src/services/as-associate.test.ts +21 -15
- package/src/services/as-associate.ts +23 -22
- package/src/services/associate-roles.test.ts +16 -22
- package/src/services/associate-roles.ts +2 -2
- package/src/services/attribute-group.test.ts +40 -44
- package/src/services/attribute-group.ts +2 -2
- package/src/services/business-units.test.ts +227 -163
- package/src/services/business-units.ts +2 -2
- package/src/services/cart-discount.test.ts +253 -187
- package/src/services/cart-discount.ts +2 -2
- package/src/services/cart.test.ts +833 -832
- package/src/services/cart.ts +31 -12
- package/src/services/category.test.ts +208 -130
- package/src/services/category.ts +2 -2
- package/src/services/channel.test.ts +39 -44
- package/src/services/channel.ts +2 -2
- package/src/services/custom-object.test.ts +103 -79
- package/src/services/custom-object.ts +106 -38
- package/src/services/customer-group.test.ts +39 -44
- package/src/services/customer-group.ts +2 -2
- package/src/services/customer.test.ts +357 -292
- package/src/services/customer.ts +70 -23
- package/src/services/discount-code.test.ts +57 -68
- package/src/services/discount-code.ts +2 -2
- package/src/services/discount-group.test.ts +111 -134
- package/src/services/discount-group.ts +2 -2
- package/src/services/draft-validation.test.ts +255 -0
- package/src/services/extension.test.ts +39 -44
- package/src/services/extension.ts +2 -2
- package/src/services/inventory-entry.test.ts +106 -87
- package/src/services/inventory-entry.ts +2 -2
- package/src/services/my-business-unit.test.ts +82 -112
- package/src/services/my-business-unit.ts +25 -19
- package/src/services/my-cart.test.ts +46 -41
- package/src/services/my-cart.ts +32 -28
- package/src/services/my-customer.test.ts +153 -88
- package/src/services/my-customer.ts +130 -61
- package/src/services/my-order.ts +15 -12
- package/src/services/my-payment.test.ts +30 -24
- package/src/services/my-payment.ts +2 -2
- package/src/services/my-shopping-list.ts +2 -2
- package/src/services/order.test.ts +332 -276
- package/src/services/order.ts +45 -27
- package/src/services/payment.test.ts +31 -29
- package/src/services/payment.ts +2 -2
- package/src/services/product-discount.test.ts +39 -46
- package/src/services/product-discount.ts +2 -2
- package/src/services/product-projection.test.ts +176 -166
- package/src/services/product-projection.ts +31 -15
- package/src/services/product-selection.test.ts +17 -9
- package/src/services/product-selection.ts +2 -2
- package/src/services/product-type.test.ts +80 -21
- package/src/services/product-type.ts +2 -2
- package/src/services/product.test.ts +569 -534
- package/src/services/product.ts +14 -7
- package/src/services/project.test.ts +22 -12
- package/src/services/project.ts +28 -13
- package/src/services/quote-request.test.ts +36 -39
- package/src/services/quote-request.ts +2 -2
- package/src/services/quote-staged.ts +2 -2
- package/src/services/quote.ts +2 -2
- package/src/services/recurrence-policy.test.ts +114 -139
- package/src/services/recurrence-policy.ts +2 -2
- package/src/services/recurring-order.test.ts +149 -194
- package/src/services/recurring-order.ts +2 -2
- package/src/services/reviews.test.ts +127 -106
- package/src/services/reviews.ts +2 -2
- package/src/services/shipping-method.test.ts +96 -125
- package/src/services/shipping-method.ts +24 -12
- package/src/services/shopping-list.test.ts +183 -141
- package/src/services/shopping-list.ts +2 -2
- package/src/services/standalone-price.test.ts +60 -46
- package/src/services/standalone-price.ts +2 -2
- package/src/services/state.test.ts +20 -25
- package/src/services/state.ts +2 -2
- package/src/services/store.test.ts +26 -45
- package/src/services/store.ts +2 -2
- package/src/services/subscription.test.ts +39 -44
- package/src/services/subscription.ts +2 -2
- package/src/services/tax-category.test.ts +33 -36
- package/src/services/tax-category.ts +2 -2
- package/src/services/type.test.ts +45 -44
- package/src/services/type.ts +2 -2
- package/src/services/zone.test.ts +40 -44
- package/src/services/zone.ts +2 -2
- package/src/shipping.ts +41 -11
- package/src/storage/abstract.ts +248 -17
- package/src/storage/in-memory.ts +147 -290
- package/src/storage/sqlite.ts +429 -0
- package/src/storage/storage-map.ts +75 -0
- package/src/storage/storage.test-helpers.ts +97 -0
- package/src/storage/storage.test.ts +802 -0
- package/src/testing/associate-role.ts +28 -0
- package/src/testing/attribute-group.ts +27 -0
- package/src/testing/business-unit.ts +9 -8
- package/src/testing/cart-discount.ts +34 -0
- package/src/testing/cart.ts +20 -0
- package/src/testing/category.ts +25 -0
- package/src/testing/channel.ts +23 -0
- package/src/testing/custom-object.ts +27 -0
- package/src/testing/customer-group.ts +26 -0
- package/src/testing/customer.ts +36 -33
- package/src/testing/discount-code.ts +29 -0
- package/src/testing/discount-group.ts +27 -0
- package/src/testing/extension.ts +32 -0
- package/src/testing/index.ts +33 -0
- package/src/testing/inventory-entry.ts +26 -0
- package/src/testing/order.ts +27 -0
- package/src/testing/payment.ts +23 -0
- package/src/testing/product-discount.ts +33 -0
- package/src/testing/product-selection.ts +28 -0
- package/src/testing/product-type.ts +27 -0
- package/src/testing/product.ts +38 -0
- package/src/testing/quote-request.ts +29 -0
- package/src/testing/recurrence-policy.ts +33 -0
- package/src/testing/recurring-order.ts +32 -0
- package/src/testing/review.ts +24 -0
- package/src/testing/shipping-method.ts +31 -0
- package/src/testing/shopping-list.ts +25 -0
- package/src/testing/standalone-price.ts +31 -0
- package/src/testing/state.ts +21 -0
- package/src/testing/store.ts +26 -0
- package/src/testing/subscription.ts +38 -0
- package/src/testing/tax-category.ts +27 -0
- package/src/testing/type.ts +9 -6
- package/src/testing/zone.ts +22 -0
- package/src/validate.test.ts +122 -0
- package/src/validate.ts +78 -7
- package/src/.env +0 -0
package/src/storage/in-memory.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import assert from "node:assert";
|
|
2
1
|
import type {
|
|
3
2
|
AssociateRole,
|
|
4
3
|
AttributeGroup,
|
|
@@ -14,10 +13,8 @@ import type {
|
|
|
14
13
|
DiscountGroup,
|
|
15
14
|
Extension,
|
|
16
15
|
InvalidInputError,
|
|
17
|
-
InvalidJsonInputError,
|
|
18
16
|
InventoryEntry,
|
|
19
17
|
Order,
|
|
20
|
-
PagedQueryResponse,
|
|
21
18
|
Payment,
|
|
22
19
|
Product,
|
|
23
20
|
ProductDiscount,
|
|
@@ -29,12 +26,8 @@ import type {
|
|
|
29
26
|
QuoteRequest,
|
|
30
27
|
RecurrencePolicy,
|
|
31
28
|
RecurringOrder,
|
|
32
|
-
Reference,
|
|
33
|
-
ReferencedResourceNotFoundError,
|
|
34
|
-
ResourceIdentifier,
|
|
35
29
|
ShippingMethod,
|
|
36
30
|
ShoppingList,
|
|
37
|
-
ShoppingListLineItem,
|
|
38
31
|
StagedQuote,
|
|
39
32
|
State,
|
|
40
33
|
Store,
|
|
@@ -45,16 +38,15 @@ import type {
|
|
|
45
38
|
} from "@commercetools/platform-sdk";
|
|
46
39
|
import { CommercetoolsError } from "#src/exceptions.ts";
|
|
47
40
|
import { cloneObject } from "../helpers.ts";
|
|
48
|
-
import { parseExpandClause } from "../lib/expandParser.ts";
|
|
49
41
|
import { parseQueryExpression } from "../lib/predicateParser.ts";
|
|
50
42
|
import type {
|
|
51
43
|
PagedQueryResponseMap,
|
|
52
44
|
ResourceMap,
|
|
53
45
|
ResourceType,
|
|
54
|
-
Writable,
|
|
55
46
|
} from "../types.ts";
|
|
56
47
|
import type { GetParams, ProjectStorage, QueryParams } from "./abstract.ts";
|
|
57
48
|
import { AbstractStorage } from "./abstract.ts";
|
|
49
|
+
import { StorageMap } from "./storage-map.ts";
|
|
58
50
|
|
|
59
51
|
export class InMemoryStorage extends AbstractStorage {
|
|
60
52
|
protected resources: {
|
|
@@ -65,7 +57,10 @@ export class InMemoryStorage extends AbstractStorage {
|
|
|
65
57
|
[projectKey: string]: Project;
|
|
66
58
|
} = {};
|
|
67
59
|
|
|
68
|
-
|
|
60
|
+
// Secondary index for custom objects: projectKey -> "container\0key" -> resource id
|
|
61
|
+
private _customObjectIndex: Map<string, Map<string, string>> = new Map();
|
|
62
|
+
|
|
63
|
+
async addProject(projectKey: string): Promise<Project> {
|
|
69
64
|
if (!this.projects[projectKey]) {
|
|
70
65
|
this.projects[projectKey] = {
|
|
71
66
|
key: projectKey,
|
|
@@ -104,222 +99,221 @@ export class InMemoryStorage extends AbstractStorage {
|
|
|
104
99
|
status: "Deactivated",
|
|
105
100
|
},
|
|
106
101
|
},
|
|
102
|
+
discounts: {
|
|
103
|
+
discountCombinationMode: "Stacking",
|
|
104
|
+
},
|
|
107
105
|
version: 1,
|
|
108
106
|
};
|
|
109
107
|
}
|
|
110
108
|
return this.projects[projectKey];
|
|
111
|
-
}
|
|
109
|
+
}
|
|
112
110
|
|
|
113
|
-
saveProject
|
|
114
|
-
this.projects[project.key] = project;
|
|
111
|
+
async saveProject(project: Project): Promise<Project> {
|
|
112
|
+
this.projects[project.key] = cloneObject(project);
|
|
115
113
|
return project;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
getProject = (projectKey: string): Project => this.addProject(projectKey);
|
|
119
|
-
|
|
120
|
-
// Expand resolves a nested reference and injects the object in the given obj
|
|
121
|
-
public expand = <T>(
|
|
122
|
-
projectKey: string,
|
|
123
|
-
obj: T,
|
|
124
|
-
clause: undefined | string | string[],
|
|
125
|
-
): T => {
|
|
126
|
-
if (!clause) return obj;
|
|
127
|
-
const newObj = cloneObject(obj);
|
|
128
|
-
if (Array.isArray(clause)) {
|
|
129
|
-
for (const c of clause) {
|
|
130
|
-
this._resolveResource(projectKey, newObj, c);
|
|
131
|
-
}
|
|
132
|
-
} else {
|
|
133
|
-
this._resolveResource(projectKey, newObj, clause);
|
|
134
|
-
}
|
|
135
|
-
return newObj;
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
private _resolveResource = (projectKey: string, obj: any, expand: string) => {
|
|
139
|
-
const params = parseExpandClause(expand);
|
|
140
|
-
|
|
141
|
-
// 'lineItems[*].variant' on ShoppingList is an exception, these variants are not references
|
|
142
|
-
if (params.index === "*") {
|
|
143
|
-
const reference = obj[params.element];
|
|
144
|
-
if (
|
|
145
|
-
params.element === "lineItems" &&
|
|
146
|
-
params.rest?.startsWith("variant") &&
|
|
147
|
-
reference.every(
|
|
148
|
-
(item: any) =>
|
|
149
|
-
item.variant === undefined && item.variantId !== undefined,
|
|
150
|
-
)
|
|
151
|
-
) {
|
|
152
|
-
for (const item of reference as ShoppingListLineItem[]) {
|
|
153
|
-
this._resolveShoppingListLineItemVariant(projectKey, item);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
114
|
+
}
|
|
157
115
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
163
|
-
this._resolveReference(projectKey, reference, params.rest);
|
|
164
|
-
} else if (params.index === "*") {
|
|
165
|
-
const reference = obj[params.element];
|
|
166
|
-
if (reference === undefined || !Array.isArray(reference)) return;
|
|
167
|
-
for (const itemRef of reference as Writable<Reference>[]) {
|
|
168
|
-
this._resolveReference(projectKey, itemRef, params.rest);
|
|
169
|
-
}
|
|
170
|
-
} else {
|
|
171
|
-
const reference = obj[params.element][params.index];
|
|
172
|
-
if (reference === undefined) return;
|
|
173
|
-
this._resolveReference(projectKey, reference, params.rest);
|
|
174
|
-
}
|
|
175
|
-
};
|
|
116
|
+
async getProject(projectKey: string): Promise<Project> {
|
|
117
|
+
await this.addProject(projectKey);
|
|
118
|
+
return cloneObject(this.projects[projectKey]);
|
|
119
|
+
}
|
|
176
120
|
|
|
177
|
-
private forProjectKey(projectKey: string): ProjectStorage {
|
|
178
|
-
this.addProject(projectKey);
|
|
121
|
+
private async forProjectKey(projectKey: string): Promise<ProjectStorage> {
|
|
122
|
+
await this.addProject(projectKey);
|
|
179
123
|
|
|
180
124
|
let projectStorage = this.resources[projectKey];
|
|
181
125
|
if (!projectStorage) {
|
|
182
126
|
projectStorage = this.resources[projectKey] = {
|
|
183
|
-
"associate-role": new
|
|
184
|
-
"attribute-group": new
|
|
185
|
-
"business-unit": new
|
|
186
|
-
cart: new
|
|
187
|
-
"cart-discount": new
|
|
188
|
-
category: new
|
|
189
|
-
channel: new
|
|
190
|
-
customer: new
|
|
191
|
-
"customer-group": new
|
|
192
|
-
"discount-code": new
|
|
193
|
-
"discount-group": new
|
|
194
|
-
extension: new
|
|
195
|
-
"inventory-entry": new
|
|
196
|
-
"key-value-document": new
|
|
197
|
-
order: new
|
|
198
|
-
"order-edit": new
|
|
199
|
-
payment: new
|
|
200
|
-
product: new
|
|
201
|
-
quote: new
|
|
202
|
-
"quote-request": new
|
|
203
|
-
"product-discount": new
|
|
204
|
-
"product-selection": new
|
|
205
|
-
"product-type": new
|
|
206
|
-
"product-projection": new
|
|
207
|
-
"product-tailoring": new
|
|
208
|
-
"recurrence-policy": new
|
|
209
|
-
"recurring-order": new
|
|
210
|
-
review: new
|
|
211
|
-
"shipping-method": new
|
|
212
|
-
"staged-quote": new
|
|
213
|
-
state: new
|
|
214
|
-
store: new
|
|
215
|
-
"shopping-list": new
|
|
216
|
-
"standalone-price": new
|
|
217
|
-
subscription: new
|
|
218
|
-
"tax-category": new
|
|
219
|
-
type: new
|
|
220
|
-
zone: new
|
|
127
|
+
"associate-role": new StorageMap<string, AssociateRole>(),
|
|
128
|
+
"attribute-group": new StorageMap<string, AttributeGroup>(),
|
|
129
|
+
"business-unit": new StorageMap<string, BusinessUnit>(),
|
|
130
|
+
cart: new StorageMap<string, Cart>(),
|
|
131
|
+
"cart-discount": new StorageMap<string, CartDiscount>(),
|
|
132
|
+
category: new StorageMap<string, Category>(),
|
|
133
|
+
channel: new StorageMap<string, Channel>(),
|
|
134
|
+
customer: new StorageMap<string, Customer>(),
|
|
135
|
+
"customer-group": new StorageMap<string, CustomerGroup>(),
|
|
136
|
+
"discount-code": new StorageMap<string, DiscountCode>(),
|
|
137
|
+
"discount-group": new StorageMap<string, DiscountGroup>(),
|
|
138
|
+
extension: new StorageMap<string, Extension>(),
|
|
139
|
+
"inventory-entry": new StorageMap<string, InventoryEntry>(),
|
|
140
|
+
"key-value-document": new StorageMap<string, CustomObject>(),
|
|
141
|
+
order: new StorageMap<string, Order>(),
|
|
142
|
+
"order-edit": new StorageMap<string, any>(),
|
|
143
|
+
payment: new StorageMap<string, Payment>(),
|
|
144
|
+
product: new StorageMap<string, Product>(),
|
|
145
|
+
quote: new StorageMap<string, Quote>(),
|
|
146
|
+
"quote-request": new StorageMap<string, QuoteRequest>(),
|
|
147
|
+
"product-discount": new StorageMap<string, ProductDiscount>(),
|
|
148
|
+
"product-selection": new StorageMap<string, any>(),
|
|
149
|
+
"product-type": new StorageMap<string, ProductType>(),
|
|
150
|
+
"product-projection": new StorageMap<string, ProductProjection>(),
|
|
151
|
+
"product-tailoring": new StorageMap<string, ProductTailoring>(),
|
|
152
|
+
"recurrence-policy": new StorageMap<string, RecurrencePolicy>(),
|
|
153
|
+
"recurring-order": new StorageMap<string, RecurringOrder>(),
|
|
154
|
+
review: new StorageMap<string, any>(),
|
|
155
|
+
"shipping-method": new StorageMap<string, ShippingMethod>(),
|
|
156
|
+
"staged-quote": new StorageMap<string, StagedQuote>(),
|
|
157
|
+
state: new StorageMap<string, State>(),
|
|
158
|
+
store: new StorageMap<string, Store>(),
|
|
159
|
+
"shopping-list": new StorageMap<string, ShoppingList>(),
|
|
160
|
+
"standalone-price": new StorageMap<string, any>(),
|
|
161
|
+
subscription: new StorageMap<string, Subscription>(),
|
|
162
|
+
"tax-category": new StorageMap<string, TaxCategory>(),
|
|
163
|
+
type: new StorageMap<string, Type>(),
|
|
164
|
+
zone: new StorageMap<string, Zone>(),
|
|
221
165
|
};
|
|
222
166
|
}
|
|
223
167
|
return projectStorage;
|
|
224
168
|
}
|
|
225
169
|
|
|
226
|
-
clear() {
|
|
170
|
+
async clear(): Promise<void> {
|
|
227
171
|
for (const [, projectStorage] of Object.entries(this.resources)) {
|
|
228
172
|
for (const [, value] of Object.entries(projectStorage)) {
|
|
229
173
|
value?.clear();
|
|
230
174
|
}
|
|
231
175
|
}
|
|
176
|
+
this._customObjectIndex.clear();
|
|
232
177
|
}
|
|
233
178
|
|
|
234
|
-
all<RT extends ResourceType>(
|
|
179
|
+
async all<RT extends ResourceType>(
|
|
235
180
|
projectKey: string,
|
|
236
181
|
typeId: RT,
|
|
237
|
-
): ResourceMap[RT][] {
|
|
238
|
-
const
|
|
182
|
+
): Promise<ResourceMap[RT][]> {
|
|
183
|
+
const projectStorage = await this.forProjectKey(projectKey);
|
|
184
|
+
const store = projectStorage[typeId];
|
|
239
185
|
if (store) {
|
|
240
|
-
|
|
186
|
+
// StorageMap.values() already returns cloned values
|
|
187
|
+
return Array.from(store.values()) as ResourceMap[RT][];
|
|
241
188
|
}
|
|
242
189
|
return [];
|
|
243
190
|
}
|
|
244
191
|
|
|
245
|
-
|
|
192
|
+
async count(projectKey: string, typeId: ResourceType): Promise<number> {
|
|
193
|
+
const projectStorage = await this.forProjectKey(projectKey);
|
|
194
|
+
const store = projectStorage[typeId];
|
|
195
|
+
return store ? store.size : 0;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
async add<RT extends ResourceType>(
|
|
246
199
|
projectKey: string,
|
|
247
200
|
typeId: RT,
|
|
248
201
|
obj: ResourceMap[RT],
|
|
249
202
|
params: GetParams = {},
|
|
250
|
-
): ResourceMap[RT] {
|
|
251
|
-
const store = this.forProjectKey(projectKey);
|
|
203
|
+
): Promise<ResourceMap[RT]> {
|
|
204
|
+
const store = await this.forProjectKey(projectKey);
|
|
205
|
+
// StorageMap.set() clones the value before storing
|
|
252
206
|
store[typeId]?.set(obj.id, obj);
|
|
253
207
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
208
|
+
// Maintain secondary index for custom objects
|
|
209
|
+
if (typeId === "key-value-document") {
|
|
210
|
+
const co = obj as unknown as CustomObject;
|
|
211
|
+
let projectIndex = this._customObjectIndex.get(projectKey);
|
|
212
|
+
if (!projectIndex) {
|
|
213
|
+
projectIndex = new Map();
|
|
214
|
+
this._customObjectIndex.set(projectKey, projectIndex);
|
|
215
|
+
}
|
|
216
|
+
projectIndex.set(`${co.container}\0${co.key}`, co.id);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// StorageMap.get() returns a clone, so we get a fresh copy for expand
|
|
220
|
+
const clone = store[typeId]?.get(obj.id) as ResourceMap[RT];
|
|
221
|
+
return this.expand(projectKey, clone, params.expand);
|
|
260
222
|
}
|
|
261
223
|
|
|
262
|
-
get<RT extends ResourceType>(
|
|
224
|
+
async get<RT extends ResourceType>(
|
|
263
225
|
projectKey: string,
|
|
264
226
|
typeId: RT,
|
|
265
227
|
id: string,
|
|
266
228
|
params: GetParams = {},
|
|
267
|
-
): ResourceMap[RT] | null {
|
|
268
|
-
const
|
|
229
|
+
): Promise<ResourceMap[RT] | null> {
|
|
230
|
+
const projectStorage = await this.forProjectKey(projectKey);
|
|
231
|
+
// StorageMap.get() already returns a clone
|
|
232
|
+
const resource = projectStorage[typeId]?.get(id);
|
|
269
233
|
if (resource) {
|
|
270
|
-
const
|
|
271
|
-
return
|
|
234
|
+
const expanded = await this.expand(projectKey, resource, params.expand);
|
|
235
|
+
return expanded as ResourceMap[RT];
|
|
272
236
|
}
|
|
273
237
|
return null;
|
|
274
238
|
}
|
|
275
239
|
|
|
276
|
-
getByKey<RT extends ResourceType>(
|
|
240
|
+
async getByKey<RT extends ResourceType>(
|
|
277
241
|
projectKey: string,
|
|
278
242
|
typeId: RT,
|
|
279
243
|
key: string,
|
|
280
244
|
params: GetParams = {},
|
|
281
|
-
): ResourceMap[RT] | null {
|
|
282
|
-
const store = this.forProjectKey(projectKey);
|
|
283
|
-
const resourceStore = store[typeId];
|
|
245
|
+
): Promise<ResourceMap[RT] | null> {
|
|
246
|
+
const store = await this.forProjectKey(projectKey);
|
|
284
247
|
if (!store) {
|
|
285
248
|
throw new Error("No type");
|
|
286
249
|
}
|
|
250
|
+
const resourceStore = store[typeId];
|
|
287
251
|
|
|
252
|
+
// StorageMap.values() already returns cloned values
|
|
288
253
|
const resources: any[] = Array.from(resourceStore.values());
|
|
289
254
|
const resource = resources.find((e) => e.key === key);
|
|
290
255
|
if (resource) {
|
|
291
|
-
const
|
|
292
|
-
return
|
|
256
|
+
const expanded = await this.expand(projectKey, resource, params.expand);
|
|
257
|
+
return expanded as ResourceMap[RT];
|
|
293
258
|
}
|
|
294
259
|
return null;
|
|
295
260
|
}
|
|
296
261
|
|
|
297
|
-
delete<RT extends ResourceType>(
|
|
262
|
+
async delete<RT extends ResourceType>(
|
|
298
263
|
projectKey: string,
|
|
299
264
|
typeId: RT,
|
|
300
265
|
id: string,
|
|
301
266
|
params: GetParams = {},
|
|
302
|
-
): ResourceMap[RT] | null {
|
|
303
|
-
const resource = this.get(projectKey, typeId, id);
|
|
267
|
+
): Promise<ResourceMap[RT] | null> {
|
|
268
|
+
const resource = await this.get(projectKey, typeId, id);
|
|
304
269
|
|
|
305
270
|
if (resource) {
|
|
306
|
-
this.forProjectKey(projectKey)
|
|
271
|
+
const projectStorage = await this.forProjectKey(projectKey);
|
|
272
|
+
projectStorage[typeId]?.delete(id);
|
|
273
|
+
|
|
274
|
+
// Remove from secondary index for custom objects
|
|
275
|
+
if (typeId === "key-value-document") {
|
|
276
|
+
const co = resource as unknown as CustomObject;
|
|
277
|
+
this._customObjectIndex
|
|
278
|
+
.get(projectKey)
|
|
279
|
+
?.delete(`${co.container}\0${co.key}`);
|
|
280
|
+
}
|
|
281
|
+
|
|
307
282
|
return this.expand(projectKey, resource, params.expand);
|
|
308
283
|
}
|
|
309
284
|
return resource;
|
|
310
285
|
}
|
|
311
286
|
|
|
312
|
-
|
|
287
|
+
async getByContainerAndKey(
|
|
288
|
+
projectKey: string,
|
|
289
|
+
container: string,
|
|
290
|
+
key: string,
|
|
291
|
+
): Promise<CustomObject | null> {
|
|
292
|
+
const projectIndex = this._customObjectIndex.get(projectKey);
|
|
293
|
+
if (!projectIndex) {
|
|
294
|
+
return null;
|
|
295
|
+
}
|
|
296
|
+
const id = projectIndex.get(`${container}\0${key}`);
|
|
297
|
+
if (!id) {
|
|
298
|
+
return null;
|
|
299
|
+
}
|
|
300
|
+
const resource = await this.get(projectKey, "key-value-document", id);
|
|
301
|
+
return resource as CustomObject | null;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
async query<RT extends ResourceType>(
|
|
313
305
|
projectKey: string,
|
|
314
306
|
typeId: RT,
|
|
315
307
|
params: QueryParams,
|
|
316
|
-
): PagedQueryResponseMap[RT] {
|
|
317
|
-
const
|
|
308
|
+
): Promise<PagedQueryResponseMap[RT]> {
|
|
309
|
+
const projectStorage = await this.forProjectKey(projectKey);
|
|
310
|
+
const store = projectStorage[typeId];
|
|
318
311
|
if (!store) {
|
|
319
312
|
throw new Error("No type");
|
|
320
313
|
}
|
|
321
314
|
|
|
322
|
-
|
|
315
|
+
// all() already returns cloned values via StorageMap
|
|
316
|
+
let resources = await this.all<RT>(projectKey, typeId);
|
|
323
317
|
|
|
324
318
|
// Apply predicates
|
|
325
319
|
if (params.where) {
|
|
@@ -355,157 +349,20 @@ export class InMemoryStorage extends AbstractStorage {
|
|
|
355
349
|
|
|
356
350
|
// Expand the resources
|
|
357
351
|
if (params.expand !== undefined) {
|
|
358
|
-
resources =
|
|
359
|
-
|
|
352
|
+
resources = await Promise.all(
|
|
353
|
+
resources.map((resource) =>
|
|
354
|
+
this.expand(projectKey, resource, params.expand),
|
|
355
|
+
),
|
|
360
356
|
);
|
|
361
357
|
}
|
|
362
358
|
|
|
363
359
|
return {
|
|
364
|
-
count:
|
|
365
|
-
total:
|
|
366
|
-
offset: offset,
|
|
367
|
-
limit: limit,
|
|
368
|
-
results: resources.map(cloneObject),
|
|
369
|
-
} as PagedQueryResponseMap[RT];
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
search(
|
|
373
|
-
projectKey: string,
|
|
374
|
-
typeId: ResourceType,
|
|
375
|
-
params: QueryParams,
|
|
376
|
-
): PagedQueryResponse {
|
|
377
|
-
let resources = this.all(projectKey, typeId);
|
|
378
|
-
|
|
379
|
-
// Apply predicates
|
|
380
|
-
if (params.where) {
|
|
381
|
-
try {
|
|
382
|
-
const filterFunc = parseQueryExpression(params.where);
|
|
383
|
-
resources = resources.filter((resource) => filterFunc(resource, {}));
|
|
384
|
-
} catch (err) {
|
|
385
|
-
throw new CommercetoolsError<InvalidInputError>(
|
|
386
|
-
{
|
|
387
|
-
code: "InvalidInput",
|
|
388
|
-
message: (err as any).message,
|
|
389
|
-
},
|
|
390
|
-
400,
|
|
391
|
-
);
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
// Get the total before slicing the array
|
|
396
|
-
const totalResources = resources.length;
|
|
397
|
-
|
|
398
|
-
// Apply offset, limit
|
|
399
|
-
const offset = params.offset || 0;
|
|
400
|
-
const limit = params.limit || 20;
|
|
401
|
-
resources = resources.slice(offset, offset + limit);
|
|
402
|
-
|
|
403
|
-
// Expand the resources
|
|
404
|
-
if (params.expand !== undefined) {
|
|
405
|
-
resources = resources.map((resource) =>
|
|
406
|
-
this.expand(projectKey, resource, params.expand),
|
|
407
|
-
);
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
return {
|
|
411
|
-
count: totalResources,
|
|
412
|
-
total: resources.length,
|
|
360
|
+
count: resources.length,
|
|
361
|
+
total: totalResources,
|
|
413
362
|
offset: offset,
|
|
414
363
|
limit: limit,
|
|
364
|
+
// Resources are already clones from StorageMap
|
|
415
365
|
results: resources,
|
|
416
|
-
};
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
getByResourceIdentifier<RT extends ResourceType>(
|
|
420
|
-
projectKey: string,
|
|
421
|
-
identifier: ResourceIdentifier,
|
|
422
|
-
): ResourceMap[RT] {
|
|
423
|
-
if (identifier.id) {
|
|
424
|
-
const resource = this.get(projectKey, identifier.typeId, identifier.id);
|
|
425
|
-
if (resource) {
|
|
426
|
-
return resource as ResourceMap[RT];
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
throw new CommercetoolsError<ReferencedResourceNotFoundError>({
|
|
430
|
-
code: "ReferencedResourceNotFound",
|
|
431
|
-
message: `The referenced object of type '${identifier.typeId}' with id '${identifier.id}' was not found. It either doesn't exist, or it can't be accessed from this endpoint (e.g., if the endpoint filters by store or customer account).`,
|
|
432
|
-
typeId: identifier.typeId,
|
|
433
|
-
id: identifier.id,
|
|
434
|
-
});
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
if (identifier.key) {
|
|
438
|
-
const resource = this.getByKey(
|
|
439
|
-
projectKey,
|
|
440
|
-
identifier.typeId,
|
|
441
|
-
identifier.key,
|
|
442
|
-
);
|
|
443
|
-
if (resource) {
|
|
444
|
-
return resource as ResourceMap[RT];
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
throw new CommercetoolsError<ReferencedResourceNotFoundError>({
|
|
448
|
-
code: "ReferencedResourceNotFound",
|
|
449
|
-
message: `The referenced object of type '${identifier.typeId}' with key '${identifier.key}' was not found. It either doesn't exist, or it can't be accessed from this endpoint (e.g., if the endpoint filters by store or customer account).`,
|
|
450
|
-
typeId: identifier.typeId,
|
|
451
|
-
key: identifier.key,
|
|
452
|
-
});
|
|
453
|
-
}
|
|
454
|
-
throw new CommercetoolsError<InvalidJsonInputError>({
|
|
455
|
-
code: "InvalidJsonInput",
|
|
456
|
-
message: "Request body does not contain valid JSON.",
|
|
457
|
-
detailedErrorMessage: "ResourceIdentifier requires an 'id' xor a 'key'",
|
|
458
|
-
});
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
private _resolveReference(
|
|
462
|
-
projectKey: string,
|
|
463
|
-
reference: any,
|
|
464
|
-
expand: string | undefined,
|
|
465
|
-
) {
|
|
466
|
-
if (reference === undefined) return;
|
|
467
|
-
|
|
468
|
-
if (
|
|
469
|
-
reference.typeId !== undefined &&
|
|
470
|
-
(reference.id !== undefined || reference.key !== undefined)
|
|
471
|
-
) {
|
|
472
|
-
// First check if the object is already resolved. This is the case when
|
|
473
|
-
// the complete resource is pushed via the .add() method.
|
|
474
|
-
if (!reference.obj) {
|
|
475
|
-
reference.obj = this.getByResourceIdentifier(projectKey, {
|
|
476
|
-
typeId: reference.typeId,
|
|
477
|
-
id: reference.id,
|
|
478
|
-
key: reference.key,
|
|
479
|
-
} as ResourceIdentifier);
|
|
480
|
-
}
|
|
481
|
-
if (expand) {
|
|
482
|
-
this._resolveResource(projectKey, reference.obj, expand);
|
|
483
|
-
}
|
|
484
|
-
} else {
|
|
485
|
-
if (expand) {
|
|
486
|
-
this._resolveResource(projectKey, reference, expand);
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
private _resolveShoppingListLineItemVariant(
|
|
492
|
-
projectKey: string,
|
|
493
|
-
lineItem: ShoppingListLineItem,
|
|
494
|
-
) {
|
|
495
|
-
const product = this.getByResourceIdentifier(projectKey, {
|
|
496
|
-
typeId: "product",
|
|
497
|
-
id: lineItem.productId,
|
|
498
|
-
}) as Product | undefined;
|
|
499
|
-
|
|
500
|
-
if (!product) {
|
|
501
|
-
return;
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
const variant = [
|
|
505
|
-
product.masterData.current.masterVariant,
|
|
506
|
-
...product.masterData.current.variants,
|
|
507
|
-
].find((e) => e.id === lineItem.variantId);
|
|
508
|
-
// @ts-expect-error
|
|
509
|
-
lineItem.variant = variant;
|
|
366
|
+
} as PagedQueryResponseMap[RT];
|
|
510
367
|
}
|
|
511
368
|
}
|