@labdigital/commercetools-mock 2.65.1 → 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.
Files changed (281) hide show
  1. package/README.md +31 -8
  2. package/dist/abstract-BKFcva6S.mjs +1044 -0
  3. package/dist/abstract-BKFcva6S.mjs.map +1 -0
  4. package/dist/config-BcNSzPZz.d.mts +1718 -0
  5. package/dist/index.d.mts +50 -1633
  6. package/dist/index.mjs +3771 -2654
  7. package/dist/index.mjs.map +1 -1
  8. package/dist/storage/sqlite.d.mts +59 -0
  9. package/dist/storage/sqlite.mjs +234 -0
  10. package/dist/storage/sqlite.mjs.map +1 -0
  11. package/package.json +26 -29
  12. package/src/ctMock.ts +125 -136
  13. package/src/helpers.ts +14 -6
  14. package/src/index.ts +5 -0
  15. package/src/lib/masking.ts +4 -5
  16. package/src/lib/product-review-statistics.test.ts +257 -294
  17. package/src/lib/review-statistics.ts +17 -4
  18. package/src/oauth/helpers.ts +7 -4
  19. package/src/oauth/server.test.ts +102 -62
  20. package/src/oauth/server.ts +215 -213
  21. package/src/oauth/store.ts +20 -6
  22. package/src/orderSearch.ts +3 -3
  23. package/src/product-projection-search.ts +38 -20
  24. package/src/product-search-availability.test.ts +31 -52
  25. package/src/product-search.ts +19 -10
  26. package/src/projectAPI.ts +6 -22
  27. package/src/repositories/abstract.ts +182 -48
  28. package/src/repositories/as-associate.test.ts +19 -19
  29. package/src/repositories/associate-role.ts +12 -23
  30. package/src/repositories/attribute-group.test.ts +23 -23
  31. package/src/repositories/attribute-group.ts +6 -4
  32. package/src/repositories/business-unit.test.ts +63 -57
  33. package/src/repositories/business-unit.ts +107 -55
  34. package/src/repositories/cart/actions.ts +96 -65
  35. package/src/repositories/cart/helpers.ts +15 -11
  36. package/src/repositories/cart/index.test.ts +136 -30
  37. package/src/repositories/cart/index.ts +76 -59
  38. package/src/repositories/cart-discount/actions.ts +12 -44
  39. package/src/repositories/cart-discount/index.ts +20 -8
  40. package/src/repositories/category/actions.ts +27 -27
  41. package/src/repositories/category/index.test.ts +13 -9
  42. package/src/repositories/category/index.ts +40 -23
  43. package/src/repositories/channel.test.ts +53 -51
  44. package/src/repositories/channel.ts +12 -22
  45. package/src/repositories/custom-object.ts +34 -25
  46. package/src/repositories/customer/actions.ts +47 -25
  47. package/src/repositories/customer/index.test.ts +11 -11
  48. package/src/repositories/customer/index.ts +65 -35
  49. package/src/repositories/customer-group.test.ts +44 -42
  50. package/src/repositories/customer-group.ts +12 -22
  51. package/src/repositories/discount-code/actions.ts +3 -19
  52. package/src/repositories/discount-code/index.ts +9 -4
  53. package/src/repositories/discount-group/index.ts +8 -3
  54. package/src/repositories/extension.test.ts +27 -27
  55. package/src/repositories/extension.ts +10 -5
  56. package/src/repositories/helpers.ts +126 -47
  57. package/src/repositories/inventory-entry/actions.ts +3 -24
  58. package/src/repositories/inventory-entry/index.ts +19 -11
  59. package/src/repositories/my-customer.ts +13 -12
  60. package/src/repositories/my-order.ts +5 -2
  61. package/src/repositories/order/actions.ts +89 -56
  62. package/src/repositories/order/index.test.ts +36 -31
  63. package/src/repositories/order/index.ts +83 -49
  64. package/src/repositories/order-edit.ts +8 -3
  65. package/src/repositories/payment/actions.ts +64 -44
  66. package/src/repositories/payment/helpers.ts +3 -3
  67. package/src/repositories/payment/index.ts +28 -12
  68. package/src/repositories/product/actions.ts +133 -98
  69. package/src/repositories/product/helpers.ts +29 -16
  70. package/src/repositories/product/index.ts +42 -25
  71. package/src/repositories/product-discount.ts +6 -4
  72. package/src/repositories/product-projection.ts +41 -21
  73. package/src/repositories/product-selection.ts +8 -15
  74. package/src/repositories/product-tailoring.ts +22 -3
  75. package/src/repositories/product-type.ts +45 -4
  76. package/src/repositories/project.ts +57 -13
  77. package/src/repositories/quote/actions.ts +5 -28
  78. package/src/repositories/quote/index.ts +29 -6
  79. package/src/repositories/quote-request/actions.ts +5 -28
  80. package/src/repositories/quote-request/index.test.ts +3 -3
  81. package/src/repositories/quote-request/index.ts +31 -11
  82. package/src/repositories/quote-staged/actions.ts +5 -28
  83. package/src/repositories/quote-staged/index.ts +22 -8
  84. package/src/repositories/recurrence-policy/index.ts +6 -4
  85. package/src/repositories/recurring-order/actions.ts +7 -32
  86. package/src/repositories/recurring-order/index.ts +8 -6
  87. package/src/repositories/review.test.ts +147 -142
  88. package/src/repositories/review.ts +31 -37
  89. package/src/repositories/shipping-method/actions.ts +11 -28
  90. package/src/repositories/shipping-method/index.ts +26 -15
  91. package/src/repositories/shopping-list/actions.ts +21 -31
  92. package/src/repositories/shopping-list/index.ts +44 -22
  93. package/src/repositories/standalone-price.ts +6 -4
  94. package/src/repositories/state.ts +15 -9
  95. package/src/repositories/store.ts +21 -32
  96. package/src/repositories/subscription.test.ts +22 -22
  97. package/src/repositories/subscription.ts +8 -3
  98. package/src/repositories/tax-category/index.ts +8 -3
  99. package/src/repositories/type/actions.ts +21 -3
  100. package/src/repositories/type/index.ts +5 -3
  101. package/src/repositories/zone.test.ts +112 -77
  102. package/src/repositories/zone.ts +5 -3
  103. package/src/schemas/generated/associate-role.ts +13 -0
  104. package/src/schemas/generated/attribute-group.ts +12 -0
  105. package/src/schemas/generated/business-unit.ts +38 -0
  106. package/src/schemas/generated/cart-discount.ts +33 -0
  107. package/src/schemas/generated/cart.ts +61 -0
  108. package/src/schemas/generated/category.ts +25 -0
  109. package/src/schemas/generated/channel.ts +21 -0
  110. package/src/schemas/generated/common.ts +1372 -0
  111. package/src/schemas/generated/custom-object.ts +11 -0
  112. package/src/schemas/generated/customer-group.ts +11 -0
  113. package/src/schemas/generated/customer.ts +47 -0
  114. package/src/schemas/generated/discount-code.ts +25 -0
  115. package/src/schemas/generated/discount-group.ts +13 -0
  116. package/src/schemas/generated/extension.ts +15 -0
  117. package/src/schemas/generated/index.ts +42 -0
  118. package/src/schemas/generated/inventory-entry.ts +20 -0
  119. package/src/schemas/generated/my-quote-request.ts +10 -0
  120. package/src/schemas/generated/order-edit.ts +18 -0
  121. package/src/schemas/generated/order-from-cart.ts +25 -0
  122. package/src/schemas/generated/payment.ts +30 -0
  123. package/src/schemas/generated/product-discount.ts +20 -0
  124. package/src/schemas/generated/product-selection.ts +18 -0
  125. package/src/schemas/generated/product-tailoring.ts +26 -0
  126. package/src/schemas/generated/product-type.ts +12 -0
  127. package/src/schemas/generated/product.ts +37 -0
  128. package/src/schemas/generated/quote-request.ts +19 -0
  129. package/src/schemas/generated/quote.ts +18 -0
  130. package/src/schemas/generated/recurrence-policy.ts +15 -0
  131. package/src/schemas/generated/recurring-order.ts +19 -0
  132. package/src/schemas/generated/review.ts +24 -0
  133. package/src/schemas/generated/shipping-method.ts +24 -0
  134. package/src/schemas/generated/shopping-list.ts +28 -0
  135. package/src/schemas/generated/staged-quote.ts +18 -0
  136. package/src/schemas/generated/standalone-price.ts +32 -0
  137. package/src/schemas/generated/state.ts +20 -0
  138. package/src/schemas/generated/store.ts +23 -0
  139. package/src/schemas/generated/subscription.ts +20 -0
  140. package/src/schemas/generated/tax-category.ts +12 -0
  141. package/src/schemas/generated/type.ts +17 -0
  142. package/src/schemas/generated/zone.ts +12 -0
  143. package/src/schemas/update-request.ts +3 -5
  144. package/src/server.ts +32 -4
  145. package/src/services/abstract.ts +207 -101
  146. package/src/services/as-associate-cart.test.ts +28 -36
  147. package/src/services/as-associate-cart.ts +15 -12
  148. package/src/services/as-associate-order.test.ts +33 -40
  149. package/src/services/as-associate-order.ts +15 -12
  150. package/src/services/as-associate-quote-request.ts +15 -12
  151. package/src/services/as-associate-shopping-list.test.ts +25 -35
  152. package/src/services/as-associate-shopping-list.ts +15 -12
  153. package/src/services/as-associate.test.ts +21 -15
  154. package/src/services/as-associate.ts +23 -22
  155. package/src/services/associate-roles.test.ts +16 -22
  156. package/src/services/associate-roles.ts +2 -2
  157. package/src/services/attribute-group.test.ts +40 -44
  158. package/src/services/attribute-group.ts +2 -2
  159. package/src/services/business-units.test.ts +227 -163
  160. package/src/services/business-units.ts +2 -2
  161. package/src/services/cart-discount.test.ts +253 -187
  162. package/src/services/cart-discount.ts +2 -2
  163. package/src/services/cart.test.ts +833 -832
  164. package/src/services/cart.ts +31 -12
  165. package/src/services/category.test.ts +208 -130
  166. package/src/services/category.ts +2 -2
  167. package/src/services/channel.test.ts +39 -44
  168. package/src/services/channel.ts +2 -2
  169. package/src/services/custom-object.test.ts +103 -79
  170. package/src/services/custom-object.ts +106 -38
  171. package/src/services/customer-group.test.ts +39 -44
  172. package/src/services/customer-group.ts +2 -2
  173. package/src/services/customer.test.ts +357 -292
  174. package/src/services/customer.ts +70 -23
  175. package/src/services/discount-code.test.ts +57 -68
  176. package/src/services/discount-code.ts +2 -2
  177. package/src/services/discount-group.test.ts +111 -134
  178. package/src/services/discount-group.ts +2 -2
  179. package/src/services/draft-validation.test.ts +255 -0
  180. package/src/services/extension.test.ts +39 -44
  181. package/src/services/extension.ts +2 -2
  182. package/src/services/inventory-entry.test.ts +106 -87
  183. package/src/services/inventory-entry.ts +2 -2
  184. package/src/services/my-business-unit.test.ts +82 -112
  185. package/src/services/my-business-unit.ts +25 -19
  186. package/src/services/my-cart.test.ts +46 -41
  187. package/src/services/my-cart.ts +32 -28
  188. package/src/services/my-customer.test.ts +153 -88
  189. package/src/services/my-customer.ts +130 -61
  190. package/src/services/my-order.ts +15 -12
  191. package/src/services/my-payment.test.ts +30 -24
  192. package/src/services/my-payment.ts +2 -2
  193. package/src/services/my-shopping-list.ts +2 -2
  194. package/src/services/order.test.ts +332 -276
  195. package/src/services/order.ts +45 -27
  196. package/src/services/payment.test.ts +31 -29
  197. package/src/services/payment.ts +2 -2
  198. package/src/services/product-discount.test.ts +39 -46
  199. package/src/services/product-discount.ts +2 -2
  200. package/src/services/product-projection.test.ts +176 -166
  201. package/src/services/product-projection.ts +31 -15
  202. package/src/services/product-selection.test.ts +17 -9
  203. package/src/services/product-selection.ts +2 -2
  204. package/src/services/product-type.test.ts +80 -21
  205. package/src/services/product-type.ts +2 -2
  206. package/src/services/product.test.ts +569 -534
  207. package/src/services/product.ts +14 -7
  208. package/src/services/project.test.ts +22 -12
  209. package/src/services/project.ts +28 -13
  210. package/src/services/quote-request.test.ts +36 -39
  211. package/src/services/quote-request.ts +2 -2
  212. package/src/services/quote-staged.ts +2 -2
  213. package/src/services/quote.ts +2 -2
  214. package/src/services/recurrence-policy.test.ts +114 -139
  215. package/src/services/recurrence-policy.ts +2 -2
  216. package/src/services/recurring-order.test.ts +149 -194
  217. package/src/services/recurring-order.ts +2 -2
  218. package/src/services/reviews.test.ts +127 -106
  219. package/src/services/reviews.ts +2 -2
  220. package/src/services/shipping-method.test.ts +96 -125
  221. package/src/services/shipping-method.ts +24 -12
  222. package/src/services/shopping-list.test.ts +183 -141
  223. package/src/services/shopping-list.ts +2 -2
  224. package/src/services/standalone-price.test.ts +60 -46
  225. package/src/services/standalone-price.ts +2 -2
  226. package/src/services/state.test.ts +20 -25
  227. package/src/services/state.ts +2 -2
  228. package/src/services/store.test.ts +26 -45
  229. package/src/services/store.ts +2 -2
  230. package/src/services/subscription.test.ts +39 -44
  231. package/src/services/subscription.ts +2 -2
  232. package/src/services/tax-category.test.ts +33 -36
  233. package/src/services/tax-category.ts +2 -2
  234. package/src/services/type.test.ts +45 -44
  235. package/src/services/type.ts +2 -2
  236. package/src/services/zone.test.ts +40 -44
  237. package/src/services/zone.ts +2 -2
  238. package/src/shipping.ts +41 -11
  239. package/src/storage/abstract.ts +248 -17
  240. package/src/storage/in-memory.ts +147 -290
  241. package/src/storage/sqlite.ts +429 -0
  242. package/src/storage/storage-map.ts +75 -0
  243. package/src/storage/storage.test-helpers.ts +97 -0
  244. package/src/storage/storage.test.ts +802 -0
  245. package/src/testing/associate-role.ts +28 -0
  246. package/src/testing/attribute-group.ts +27 -0
  247. package/src/testing/business-unit.ts +9 -8
  248. package/src/testing/cart-discount.ts +34 -0
  249. package/src/testing/cart.ts +20 -0
  250. package/src/testing/category.ts +25 -0
  251. package/src/testing/channel.ts +23 -0
  252. package/src/testing/custom-object.ts +27 -0
  253. package/src/testing/customer-group.ts +26 -0
  254. package/src/testing/customer.ts +36 -33
  255. package/src/testing/discount-code.ts +29 -0
  256. package/src/testing/discount-group.ts +27 -0
  257. package/src/testing/extension.ts +32 -0
  258. package/src/testing/index.ts +33 -0
  259. package/src/testing/inventory-entry.ts +26 -0
  260. package/src/testing/order.ts +27 -0
  261. package/src/testing/payment.ts +23 -0
  262. package/src/testing/product-discount.ts +33 -0
  263. package/src/testing/product-selection.ts +28 -0
  264. package/src/testing/product-type.ts +27 -0
  265. package/src/testing/product.ts +38 -0
  266. package/src/testing/quote-request.ts +29 -0
  267. package/src/testing/recurrence-policy.ts +33 -0
  268. package/src/testing/recurring-order.ts +32 -0
  269. package/src/testing/review.ts +24 -0
  270. package/src/testing/shipping-method.ts +31 -0
  271. package/src/testing/shopping-list.ts +25 -0
  272. package/src/testing/standalone-price.ts +31 -0
  273. package/src/testing/state.ts +21 -0
  274. package/src/testing/store.ts +26 -0
  275. package/src/testing/subscription.ts +38 -0
  276. package/src/testing/tax-category.ts +27 -0
  277. package/src/testing/type.ts +9 -6
  278. package/src/testing/zone.ts +22 -0
  279. package/src/validate.test.ts +122 -0
  280. package/src/validate.ts +78 -7
  281. package/src/.env +0 -0
@@ -1,14 +1,27 @@
1
1
  import type {
2
2
  BaseResource,
3
+ CustomObject,
4
+ InvalidInputError,
5
+ InvalidJsonInputError,
6
+ PagedQueryResponse,
7
+ Product,
3
8
  Project,
4
9
  QueryParam,
10
+ Reference,
11
+ ReferencedResourceNotFoundError,
5
12
  ResourceIdentifier,
13
+ ShoppingListLineItem,
6
14
  } from "@commercetools/platform-sdk";
15
+ import { CommercetoolsError } from "#src/exceptions.ts";
16
+ import { parseExpandClause } from "../lib/expandParser.ts";
17
+ import { parseQueryExpression } from "../lib/predicateParser.ts";
7
18
  import type {
8
19
  PagedQueryResponseMap,
9
20
  ResourceMap,
10
21
  ResourceType,
22
+ Writable,
11
23
  } from "../types.ts";
24
+ import type { StorageMap } from "./storage-map.ts";
12
25
 
13
26
  export type GetParams = {
14
27
  expand?: string[];
@@ -25,64 +38,282 @@ export type QueryParams = {
25
38
  };
26
39
 
27
40
  export abstract class AbstractStorage {
28
- abstract clear(): void;
41
+ /**
42
+ * Close the storage backend and release any resources.
43
+ * Override this in subclasses that hold external resources (e.g. database connections).
44
+ */
45
+ close(): void {}
46
+
47
+ abstract clear(): Promise<void>;
29
48
 
30
49
  abstract all<RT extends ResourceType>(
31
50
  projectKey: string,
32
51
  typeId: RT,
33
- ): Array<ResourceMap[RT]>;
52
+ ): Promise<Array<ResourceMap[RT]>>;
53
+
54
+ /**
55
+ * Return the number of resources of the given type.
56
+ * This is more efficient than loading all resources and counting them.
57
+ */
58
+ abstract count(projectKey: string, typeId: ResourceType): Promise<number>;
34
59
 
35
60
  abstract add<RT extends ResourceType>(
36
61
  projectKey: string,
37
62
  typeId: RT,
38
63
  obj: ResourceMap[RT],
39
- ): ResourceMap[RT];
64
+ params?: GetParams,
65
+ ): Promise<ResourceMap[RT]>;
40
66
 
41
67
  abstract get<RT extends ResourceType>(
42
68
  projectKey: string,
43
69
  typeId: RT,
44
70
  id: string,
45
71
  params?: GetParams,
46
- ): ResourceMap[RT] | null;
72
+ ): Promise<ResourceMap[RT] | null>;
47
73
 
48
74
  abstract getByKey<RT extends ResourceType>(
49
75
  projectKey: string,
50
76
  typeId: RT,
51
77
  key: string,
52
- params: GetParams,
53
- ): ResourceMap[RT] | null;
78
+ params?: GetParams,
79
+ ): Promise<ResourceMap[RT] | null>;
54
80
 
55
- abstract addProject(projectKey: string): Project;
81
+ abstract addProject(projectKey: string): Promise<Project>;
56
82
 
57
- abstract getProject(projectKey: string): Project;
83
+ abstract getProject(projectKey: string): Promise<Project>;
58
84
 
59
- abstract saveProject(project: Project): Project;
85
+ abstract saveProject(project: Project): Promise<Project>;
60
86
 
61
87
  abstract delete<RT extends ResourceType>(
62
88
  projectKey: string,
63
89
  typeId: RT,
64
90
  id: string,
65
91
  params: GetParams,
66
- ): ResourceMap[RT] | null;
92
+ ): Promise<ResourceMap[RT] | null>;
67
93
 
68
94
  abstract query<RT extends ResourceType>(
69
95
  projectKey: string,
70
96
  typeId: RT,
71
97
  params: QueryParams,
72
- ): PagedQueryResponseMap[RT];
98
+ ): Promise<PagedQueryResponseMap[RT]>;
73
99
 
74
- abstract getByResourceIdentifier<RT extends ResourceType>(
100
+ /**
101
+ * Look up a custom object by its container and key.
102
+ * This is an O(1) operation for storage backends that maintain
103
+ * a secondary index on (container, key).
104
+ */
105
+ abstract getByContainerAndKey(
75
106
  projectKey: string,
76
- identifier: ResourceIdentifier,
77
- ): ResourceMap[RT];
107
+ container: string,
108
+ key: string,
109
+ ): Promise<CustomObject | null>;
78
110
 
79
- abstract expand<T>(
111
+ // Expand resolves a nested reference and injects the object in the given obj.
112
+ // NOTE: This method mutates the passed object in-place. Callers must ensure
113
+ // they pass an object that is safe to mutate (e.g. a clone from StorageMap
114
+ // or JSON.parse).
115
+ async expand<T>(
80
116
  projectKey: string,
81
117
  obj: T,
82
118
  clause: undefined | string | string[],
83
- ): T;
119
+ ): Promise<T> {
120
+ if (!clause) return obj;
121
+ if (Array.isArray(clause)) {
122
+ for (const c of clause) {
123
+ await this._resolveResource(projectKey, obj, c);
124
+ }
125
+ } else {
126
+ await this._resolveResource(projectKey, obj, clause);
127
+ }
128
+ return obj;
129
+ }
130
+
131
+ async getByResourceIdentifier<RT extends ResourceType>(
132
+ projectKey: string,
133
+ identifier: ResourceIdentifier,
134
+ ): Promise<ResourceMap[RT]> {
135
+ if (identifier.id) {
136
+ const resource = await this.get(
137
+ projectKey,
138
+ identifier.typeId,
139
+ identifier.id,
140
+ );
141
+ if (resource) {
142
+ return resource as ResourceMap[RT];
143
+ }
144
+
145
+ throw new CommercetoolsError<ReferencedResourceNotFoundError>({
146
+ code: "ReferencedResourceNotFound",
147
+ 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).`,
148
+ typeId: identifier.typeId,
149
+ id: identifier.id,
150
+ });
151
+ }
152
+
153
+ if (identifier.key) {
154
+ const resource = await this.getByKey(
155
+ projectKey,
156
+ identifier.typeId,
157
+ identifier.key,
158
+ );
159
+ if (resource) {
160
+ return resource as ResourceMap[RT];
161
+ }
162
+
163
+ throw new CommercetoolsError<ReferencedResourceNotFoundError>({
164
+ code: "ReferencedResourceNotFound",
165
+ 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).`,
166
+ typeId: identifier.typeId,
167
+ key: identifier.key,
168
+ });
169
+ }
170
+ throw new CommercetoolsError<InvalidJsonInputError>({
171
+ code: "InvalidJsonInput",
172
+ message: "Request body does not contain valid JSON.",
173
+ detailedErrorMessage: "ResourceIdentifier requires an 'id' xor a 'key'",
174
+ });
175
+ }
176
+
177
+ async search(
178
+ projectKey: string,
179
+ typeId: ResourceType,
180
+ params: QueryParams,
181
+ ): Promise<PagedQueryResponse> {
182
+ let resources = await this.all(projectKey, typeId);
183
+
184
+ // Apply predicates
185
+ if (params.where) {
186
+ try {
187
+ const filterFunc = parseQueryExpression(params.where);
188
+ resources = resources.filter((resource) => filterFunc(resource, {}));
189
+ } catch (err) {
190
+ throw new CommercetoolsError<InvalidInputError>(
191
+ {
192
+ code: "InvalidInput",
193
+ message: (err as any).message,
194
+ },
195
+ 400,
196
+ );
197
+ }
198
+ }
199
+
200
+ // Get the total before slicing the array
201
+ const totalResources = resources.length;
202
+
203
+ // Apply offset, limit
204
+ const offset = params.offset || 0;
205
+ const limit = params.limit || 20;
206
+ resources = resources.slice(offset, offset + limit);
207
+
208
+ // Expand the resources
209
+ if (params.expand !== undefined) {
210
+ resources = await Promise.all(
211
+ resources.map((resource) =>
212
+ this.expand(projectKey, resource, params.expand),
213
+ ),
214
+ );
215
+ }
216
+
217
+ return {
218
+ count: resources.length,
219
+ total: totalResources,
220
+ offset: offset,
221
+ limit: limit,
222
+ results: resources,
223
+ };
224
+ }
225
+
226
+ private async _resolveResource(projectKey: string, obj: any, expand: string) {
227
+ const params = parseExpandClause(expand);
228
+
229
+ // 'lineItems[*].variant' on ShoppingList is an exception, these variants are not references
230
+ if (params.index === "*") {
231
+ const reference = obj[params.element];
232
+ if (
233
+ params.element === "lineItems" &&
234
+ params.rest?.startsWith("variant") &&
235
+ reference.every(
236
+ (item: any) =>
237
+ item.variant === undefined && item.variantId !== undefined,
238
+ )
239
+ ) {
240
+ for (const item of reference as ShoppingListLineItem[]) {
241
+ await this._resolveShoppingListLineItemVariant(projectKey, item);
242
+ }
243
+ }
244
+ }
245
+
246
+ if (!params.index) {
247
+ const reference = obj[params.element];
248
+ if (reference === undefined) {
249
+ return;
250
+ }
251
+ await this._resolveReference(projectKey, reference, params.rest);
252
+ } else if (params.index === "*") {
253
+ const reference = obj[params.element];
254
+ if (reference === undefined || !Array.isArray(reference)) return;
255
+ for (const itemRef of reference as Writable<Reference>[]) {
256
+ await this._resolveReference(projectKey, itemRef, params.rest);
257
+ }
258
+ } else {
259
+ const reference = obj[params.element][params.index];
260
+ if (reference === undefined) return;
261
+ await this._resolveReference(projectKey, reference, params.rest);
262
+ }
263
+ }
264
+
265
+ private async _resolveReference(
266
+ projectKey: string,
267
+ reference: any,
268
+ expand: string | undefined,
269
+ ) {
270
+ if (reference === undefined) return;
271
+
272
+ if (
273
+ reference.typeId !== undefined &&
274
+ (reference.id !== undefined || reference.key !== undefined)
275
+ ) {
276
+ // First check if the object is already resolved. This is the case when
277
+ // the complete resource is pushed via the .add() method.
278
+ if (!reference.obj) {
279
+ reference.obj = await this.getByResourceIdentifier(projectKey, {
280
+ typeId: reference.typeId,
281
+ id: reference.id,
282
+ key: reference.key,
283
+ } as ResourceIdentifier);
284
+ }
285
+ if (expand) {
286
+ await this._resolveResource(projectKey, reference.obj, expand);
287
+ }
288
+ } else {
289
+ if (expand) {
290
+ await this._resolveResource(projectKey, reference, expand);
291
+ }
292
+ }
293
+ }
294
+
295
+ private async _resolveShoppingListLineItemVariant(
296
+ projectKey: string,
297
+ lineItem: ShoppingListLineItem,
298
+ ) {
299
+ const product = (await this.getByResourceIdentifier(projectKey, {
300
+ typeId: "product",
301
+ id: lineItem.productId,
302
+ })) as Product | undefined;
303
+
304
+ if (!product) {
305
+ return;
306
+ }
307
+
308
+ const variant = [
309
+ product.masterData.current.masterVariant,
310
+ ...product.masterData.current.variants,
311
+ ].find((e) => e.id === lineItem.variantId);
312
+ // @ts-expect-error
313
+ lineItem.variant = variant;
314
+ }
84
315
  }
85
316
 
86
317
  export type ProjectStorage = {
87
- [index in ResourceType]: Map<string, BaseResource>;
318
+ [index in ResourceType]: StorageMap<string, BaseResource>;
88
319
  };