@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/ctMock.ts
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import express from "express";
|
|
3
|
-
import inject from "light-my-request";
|
|
4
|
-
import morgan from "morgan";
|
|
1
|
+
import Fastify, { type FastifyBaseLogger, type FastifyInstance } from "fastify";
|
|
5
2
|
import { HttpResponse, http } from "msw";
|
|
6
3
|
import type { SetupServer, SetupServerApi } from "msw/node";
|
|
7
|
-
import
|
|
4
|
+
import qs from "qs";
|
|
8
5
|
import type { Config } from "./config.ts";
|
|
9
6
|
import { DEFAULT_API_HOSTNAME, DEFAULT_AUTH_HOSTNAME } from "./constants.ts";
|
|
10
7
|
import { CommercetoolsError } from "./exceptions.ts";
|
|
@@ -28,10 +25,10 @@ export type CommercetoolsMockOptions = {
|
|
|
28
25
|
authHost: RegExp | string;
|
|
29
26
|
silent: boolean;
|
|
30
27
|
strict: boolean;
|
|
28
|
+
storage: AbstractStorage | undefined;
|
|
29
|
+
logger: FastifyBaseLogger | undefined;
|
|
31
30
|
};
|
|
32
31
|
|
|
33
|
-
type AppOptions = { silent?: boolean };
|
|
34
|
-
|
|
35
32
|
const DEFAULT_OPTIONS: CommercetoolsMockOptions = {
|
|
36
33
|
enableAuthentication: false,
|
|
37
34
|
validateCredentials: false,
|
|
@@ -40,12 +37,14 @@ const DEFAULT_OPTIONS: CommercetoolsMockOptions = {
|
|
|
40
37
|
authHost: DEFAULT_AUTH_HOSTNAME,
|
|
41
38
|
silent: true,
|
|
42
39
|
strict: false,
|
|
40
|
+
storage: undefined,
|
|
41
|
+
logger: undefined,
|
|
43
42
|
};
|
|
44
43
|
|
|
45
44
|
const _globalListeners: SetupServer[] = [];
|
|
46
45
|
|
|
47
46
|
export class CommercetoolsMock {
|
|
48
|
-
public app:
|
|
47
|
+
public app: FastifyInstance;
|
|
49
48
|
|
|
50
49
|
public options: CommercetoolsMockOptions;
|
|
51
50
|
|
|
@@ -65,37 +64,21 @@ export class CommercetoolsMock {
|
|
|
65
64
|
this._repositories = null;
|
|
66
65
|
this._projectService = undefined;
|
|
67
66
|
|
|
68
|
-
this._storage = new InMemoryStorage();
|
|
67
|
+
this._storage = this.options.storage ?? new InMemoryStorage();
|
|
69
68
|
this._oauth2 = new OAuth2Server({
|
|
70
69
|
enabled: this.options.enableAuthentication,
|
|
71
70
|
validate: this.options.validateCredentials,
|
|
72
71
|
});
|
|
73
72
|
|
|
74
|
-
this.app = this.createApp(
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
start() {
|
|
78
|
-
process.emitWarning(
|
|
79
|
-
"The start() method is deprecated, use .registerHandlers() to bind to an msw server instead",
|
|
80
|
-
"DeprecationWarning",
|
|
81
|
-
);
|
|
82
|
-
|
|
83
|
-
// Order is important here when the hostnames match
|
|
84
|
-
this.clear();
|
|
85
|
-
this.startServer();
|
|
73
|
+
this.app = this.createApp();
|
|
86
74
|
}
|
|
87
75
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
"The stop() method is deprecated, use .registerHandlers() to bind to an msw server instead",
|
|
91
|
-
"DeprecationWarning",
|
|
92
|
-
);
|
|
93
|
-
this._mswServer?.close();
|
|
94
|
-
this._mswServer = undefined;
|
|
76
|
+
get server() {
|
|
77
|
+
return this.app.server;
|
|
95
78
|
}
|
|
96
79
|
|
|
97
|
-
clear() {
|
|
98
|
-
this._storage.clear();
|
|
80
|
+
async clear() {
|
|
81
|
+
await this._storage.clear();
|
|
99
82
|
}
|
|
100
83
|
|
|
101
84
|
project(projectKey?: string) {
|
|
@@ -123,12 +106,11 @@ export class CommercetoolsMock {
|
|
|
123
106
|
return this._oauth2.store;
|
|
124
107
|
}
|
|
125
108
|
|
|
126
|
-
runServer(port = 3000
|
|
127
|
-
|
|
128
|
-
server.keepAliveTimeout = 60 * 1000;
|
|
109
|
+
async runServer(port = 3000) {
|
|
110
|
+
await this.app.listen({ port, host: "0.0.0.0" });
|
|
129
111
|
}
|
|
130
112
|
|
|
131
|
-
private createApp(
|
|
113
|
+
private createApp(): FastifyInstance {
|
|
132
114
|
const config: Config = {
|
|
133
115
|
strict: this.options.strict,
|
|
134
116
|
storage: this._storage,
|
|
@@ -136,59 +118,92 @@ export class CommercetoolsMock {
|
|
|
136
118
|
this._repositories = createRepositories(config);
|
|
137
119
|
this._oauth2.setCustomerRepository(this._repositories.customer);
|
|
138
120
|
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
121
|
+
const loggerConfig = this.options.logger
|
|
122
|
+
? { loggerInstance: this.options.logger }
|
|
123
|
+
: { logger: !this.options.silent ? { level: "info" as const } : false };
|
|
142
124
|
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
if (this.options.enableAuthentication) {
|
|
152
|
-
app.use("/:projectKey", this._oauth2.createMiddleware(), projectRouter);
|
|
153
|
-
app.use(
|
|
154
|
-
"/:projectKey/in-store/key=:storeKey",
|
|
155
|
-
this._oauth2.createMiddleware(),
|
|
156
|
-
projectRouter,
|
|
157
|
-
);
|
|
158
|
-
} else {
|
|
159
|
-
app.use("/:projectKey", projectRouter);
|
|
160
|
-
app.use("/:projectKey/in-store/key=:storeKey", projectRouter);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// Register the rest api services in the router
|
|
164
|
-
createServices(projectRouter, this._repositories);
|
|
165
|
-
this._projectService = new ProjectService(
|
|
166
|
-
projectRouter,
|
|
167
|
-
this._repositories.project as ProjectRepository,
|
|
168
|
-
);
|
|
125
|
+
const app = Fastify({
|
|
126
|
+
// Set limit to 16mb, this is the maximum size allowed by the commercetools API: https://docs.commercetools.com/api/limits
|
|
127
|
+
bodyLimit: 16 * 1024 * 1024,
|
|
128
|
+
...loggerConfig,
|
|
129
|
+
routerOptions: {
|
|
130
|
+
querystringParser: (str) => qs.parse(str),
|
|
131
|
+
},
|
|
132
|
+
});
|
|
169
133
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
134
|
+
// Override the default JSON parser to accept empty bodies. This is
|
|
135
|
+
// needed because some HTTP clients (e.g. commercetools SDKs) send
|
|
136
|
+
// DELETE requests with a Content-Type: application/json header but
|
|
137
|
+
// without a body. Fastify 5 rejects these by default.
|
|
138
|
+
app.addContentTypeParser(
|
|
139
|
+
"application/json",
|
|
140
|
+
{ parseAs: "string" },
|
|
141
|
+
(_req, body, done) => {
|
|
142
|
+
if (!body || (typeof body === "string" && body.trim() === "")) {
|
|
143
|
+
done(null, undefined);
|
|
178
144
|
return;
|
|
179
145
|
}
|
|
146
|
+
try {
|
|
147
|
+
done(null, JSON.parse(body as string));
|
|
148
|
+
} catch (err) {
|
|
149
|
+
done(err as Error, undefined);
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
);
|
|
180
153
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
154
|
+
// Register OAuth routes
|
|
155
|
+
app.register(this._oauth2.createPlugin(), { prefix: "/oauth" });
|
|
156
|
+
|
|
157
|
+
// Register project routes
|
|
158
|
+
const repositories = this._repositories;
|
|
159
|
+
const oauth2 = this._oauth2;
|
|
160
|
+
const enableAuth = this.options.enableAuthentication;
|
|
161
|
+
|
|
162
|
+
const projectPlugin = async (instance: FastifyInstance) => {
|
|
163
|
+
if (enableAuth) {
|
|
164
|
+
instance.addHook("preHandler", oauth2.createMiddleware());
|
|
187
165
|
}
|
|
188
|
-
|
|
189
|
-
|
|
166
|
+
createServices(instance, repositories);
|
|
167
|
+
new ProjectService(instance, repositories.project as ProjectRepository);
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
app.register(projectPlugin, { prefix: "/:projectKey" });
|
|
171
|
+
app.register(projectPlugin, {
|
|
172
|
+
prefix: "/:projectKey/in-store/key=:storeKey",
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
// Error handler
|
|
176
|
+
app.setErrorHandler((error, request, reply) => {
|
|
177
|
+
if (error instanceof CommercetoolsError) {
|
|
178
|
+
const responseBody =
|
|
179
|
+
error.errors?.length > 0
|
|
180
|
+
? {
|
|
181
|
+
statusCode: error.statusCode,
|
|
182
|
+
message: error.message,
|
|
183
|
+
errors: error.errors,
|
|
184
|
+
}
|
|
185
|
+
: {
|
|
186
|
+
statusCode: error.statusCode,
|
|
187
|
+
message: error.message,
|
|
188
|
+
errors: [error.info],
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
request.log.error(
|
|
192
|
+
{ statusCode: error.statusCode, err: error },
|
|
193
|
+
`${request.method} ${request.url} - ${error.statusCode}: ${error.message}`,
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
return reply.status(error.statusCode).send(responseBody);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
request.log.error(
|
|
200
|
+
{ statusCode: 500, err: error },
|
|
201
|
+
`${request.method} ${request.url} - 500: ${error instanceof Error ? error.message : String(error)}`,
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
return reply.status(500).send({
|
|
205
|
+
error: error instanceof Error ? error.message : String(error),
|
|
190
206
|
});
|
|
191
|
-
return;
|
|
192
207
|
});
|
|
193
208
|
|
|
194
209
|
return app;
|
|
@@ -210,11 +225,12 @@ export class CommercetoolsMock {
|
|
|
210
225
|
const url = new URL(request.url);
|
|
211
226
|
const headers = copyHeaders(request.headers);
|
|
212
227
|
|
|
213
|
-
const res = await inject(
|
|
214
|
-
|
|
215
|
-
.
|
|
216
|
-
|
|
217
|
-
|
|
228
|
+
const res = await app.inject({
|
|
229
|
+
method: "POST",
|
|
230
|
+
url: `${url.pathname}?${url.searchParams.toString()}`,
|
|
231
|
+
body,
|
|
232
|
+
headers,
|
|
233
|
+
});
|
|
218
234
|
return new HttpResponse(res.body, {
|
|
219
235
|
status: res.statusCode,
|
|
220
236
|
headers: mapHeaderType(res.headers),
|
|
@@ -225,16 +241,15 @@ export class CommercetoolsMock {
|
|
|
225
241
|
const url = new URL(request.url);
|
|
226
242
|
const headers = copyHeaders(request.headers);
|
|
227
243
|
|
|
228
|
-
const res = await inject(
|
|
229
|
-
|
|
230
|
-
.
|
|
231
|
-
|
|
232
|
-
|
|
244
|
+
const res = await app.inject({
|
|
245
|
+
method: "GET",
|
|
246
|
+
url: `${url.pathname}?${url.searchParams.toString()}`,
|
|
247
|
+
body,
|
|
248
|
+
headers,
|
|
249
|
+
});
|
|
233
250
|
|
|
234
251
|
if (res.statusCode === 200) {
|
|
235
252
|
const parsedBody = JSON.parse(res.body);
|
|
236
|
-
// Check if we have a count property (e.g. for query-lookups)
|
|
237
|
-
// or if we have a result object (e.g. for single lookups)
|
|
238
253
|
const resultCount =
|
|
239
254
|
"count" in parsedBody
|
|
240
255
|
? parsedBody.count
|
|
@@ -256,11 +271,12 @@ export class CommercetoolsMock {
|
|
|
256
271
|
const url = new URL(request.url);
|
|
257
272
|
const headers = copyHeaders(request.headers);
|
|
258
273
|
|
|
259
|
-
const res = await inject(
|
|
260
|
-
|
|
261
|
-
.
|
|
262
|
-
|
|
263
|
-
|
|
274
|
+
const res = await app.inject({
|
|
275
|
+
method: "GET",
|
|
276
|
+
url: `${url.pathname}?${url.searchParams.toString()}`,
|
|
277
|
+
body,
|
|
278
|
+
headers,
|
|
279
|
+
});
|
|
264
280
|
return new HttpResponse(res.body, {
|
|
265
281
|
status: res.statusCode,
|
|
266
282
|
headers: mapHeaderType(res.headers),
|
|
@@ -271,11 +287,12 @@ export class CommercetoolsMock {
|
|
|
271
287
|
const url = new URL(request.url);
|
|
272
288
|
const headers = copyHeaders(request.headers);
|
|
273
289
|
|
|
274
|
-
const res = await inject(
|
|
275
|
-
|
|
276
|
-
.
|
|
277
|
-
|
|
278
|
-
|
|
290
|
+
const res = await app.inject({
|
|
291
|
+
method: "POST",
|
|
292
|
+
url: `${url.pathname}?${url.searchParams.toString()}`,
|
|
293
|
+
body,
|
|
294
|
+
headers,
|
|
295
|
+
});
|
|
279
296
|
return new HttpResponse(res.body, {
|
|
280
297
|
status: res.statusCode,
|
|
281
298
|
headers: mapHeaderType(res.headers),
|
|
@@ -286,11 +303,12 @@ export class CommercetoolsMock {
|
|
|
286
303
|
const url = new URL(request.url);
|
|
287
304
|
const headers = copyHeaders(request.headers);
|
|
288
305
|
|
|
289
|
-
const res = await inject(
|
|
290
|
-
|
|
291
|
-
.
|
|
292
|
-
|
|
293
|
-
|
|
306
|
+
const res = await app.inject({
|
|
307
|
+
method: "DELETE",
|
|
308
|
+
url: `${url.pathname}?${url.searchParams.toString()}`,
|
|
309
|
+
body,
|
|
310
|
+
headers,
|
|
311
|
+
});
|
|
294
312
|
return new HttpResponse(res.body, {
|
|
295
313
|
status: res.statusCode,
|
|
296
314
|
headers: mapHeaderType(res.headers),
|
|
@@ -302,33 +320,4 @@ export class CommercetoolsMock {
|
|
|
302
320
|
public mswServer() {
|
|
303
321
|
return this._mswServer;
|
|
304
322
|
}
|
|
305
|
-
|
|
306
|
-
private startServer() {
|
|
307
|
-
// Check if there are any other servers running
|
|
308
|
-
if (_globalListeners.length > 0) {
|
|
309
|
-
if (this._mswServer !== undefined) {
|
|
310
|
-
throw new Error("Server already started");
|
|
311
|
-
}
|
|
312
|
-
process.emitWarning("Server wasn't stopped properly, clearing");
|
|
313
|
-
for (const listener of _globalListeners) {
|
|
314
|
-
listener.close();
|
|
315
|
-
}
|
|
316
|
-
_globalListeners.length = 0;
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
const server = setupServer();
|
|
320
|
-
this.registerHandlers(server);
|
|
321
|
-
server.listen({
|
|
322
|
-
// We need to allow requests done by supertest
|
|
323
|
-
onUnhandledRequest: (request, print) => {
|
|
324
|
-
const url = new URL(request.url);
|
|
325
|
-
if (url.hostname === "127.0.0.1") {
|
|
326
|
-
return;
|
|
327
|
-
}
|
|
328
|
-
print.error();
|
|
329
|
-
},
|
|
330
|
-
});
|
|
331
|
-
_globalListeners.push(server);
|
|
332
|
-
this._mswServer = server;
|
|
333
|
-
}
|
|
334
323
|
}
|
package/src/helpers.ts
CHANGED
|
@@ -2,12 +2,20 @@ import type { OutgoingHttpHeaders } from "node:http";
|
|
|
2
2
|
import type { ParsedQs } from "qs";
|
|
3
3
|
import { v4 as uuidv4 } from "uuid";
|
|
4
4
|
|
|
5
|
-
export const getBaseResourceProperties = () =>
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
export const getBaseResourceProperties = (clientId?: string) => {
|
|
6
|
+
const clientInfo = {
|
|
7
|
+
clientId: clientId ?? "",
|
|
8
|
+
isPlatformClient: false,
|
|
9
|
+
};
|
|
10
|
+
return {
|
|
11
|
+
id: uuidv4(),
|
|
12
|
+
createdAt: new Date().toISOString(),
|
|
13
|
+
lastModifiedAt: new Date().toISOString(),
|
|
14
|
+
version: 0,
|
|
15
|
+
createdBy: clientInfo,
|
|
16
|
+
lastModifiedBy: clientInfo,
|
|
17
|
+
};
|
|
18
|
+
};
|
|
11
19
|
|
|
12
20
|
/**
|
|
13
21
|
* Do a nested lookup by using a path. For example `foo.bar.value` will
|
package/src/index.ts
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import type { CommercetoolsMockOptions } from "./ctMock.ts";
|
|
2
2
|
import { CommercetoolsMock } from "./ctMock.ts";
|
|
3
3
|
import { getBaseResourceProperties } from "./helpers.ts";
|
|
4
|
+
import { AbstractStorage, InMemoryStorage } from "./storage/index.ts";
|
|
5
|
+
|
|
6
|
+
export type { FastifyBaseLogger } from "fastify";
|
|
4
7
|
|
|
5
8
|
export {
|
|
9
|
+
AbstractStorage,
|
|
6
10
|
CommercetoolsMock,
|
|
11
|
+
InMemoryStorage,
|
|
7
12
|
getBaseResourceProperties,
|
|
8
13
|
type CommercetoolsMockOptions,
|
|
9
14
|
};
|
package/src/lib/masking.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { cloneObject } from "../helpers.ts";
|
|
2
|
-
|
|
3
1
|
export const maskSecretValue = <T>(resource: T, path: string): T => {
|
|
4
2
|
const parts = path.split(".");
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
// Callers are expected to pass objects that are safe to mutate
|
|
4
|
+
// (e.g. clones from storage retrieval).
|
|
5
|
+
let val = resource as any;
|
|
7
6
|
|
|
8
7
|
const target = parts.pop();
|
|
9
8
|
for (let i = 0; i < parts.length; i++) {
|
|
@@ -18,5 +17,5 @@ export const maskSecretValue = <T>(resource: T, path: string): T => {
|
|
|
18
17
|
if (val && target && val[target]) {
|
|
19
18
|
val[target] = "****";
|
|
20
19
|
}
|
|
21
|
-
return
|
|
20
|
+
return resource;
|
|
22
21
|
};
|