@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.
- 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 +3771 -2654
- 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 +89 -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
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
QuoteRequest,
|
|
3
|
+
QuoteRequestDraft,
|
|
4
|
+
} from "@commercetools/platform-sdk";
|
|
5
|
+
import { Factory } from "fishery";
|
|
6
|
+
import type { CommercetoolsMock } from "#src/ctMock.ts";
|
|
7
|
+
|
|
8
|
+
export const quoteRequestDraftFactory = (m: CommercetoolsMock) =>
|
|
9
|
+
Factory.define<QuoteRequestDraft, QuoteRequestDraft, QuoteRequest>(
|
|
10
|
+
({ onCreate }) => {
|
|
11
|
+
onCreate(async (draft) => {
|
|
12
|
+
const response = await m.app.inject({
|
|
13
|
+
method: "POST",
|
|
14
|
+
url: "/dummy/quote-requests",
|
|
15
|
+
payload: draft,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
return response.json();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
cart: {
|
|
23
|
+
typeId: "cart" as const,
|
|
24
|
+
id: "placeholder-cart-id",
|
|
25
|
+
},
|
|
26
|
+
cartVersion: 1,
|
|
27
|
+
};
|
|
28
|
+
},
|
|
29
|
+
);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
RecurrencePolicy,
|
|
3
|
+
RecurrencePolicyDraft,
|
|
4
|
+
} from "@commercetools/platform-sdk";
|
|
5
|
+
import { Factory } from "fishery";
|
|
6
|
+
import type { CommercetoolsMock } from "#src/ctMock.ts";
|
|
7
|
+
|
|
8
|
+
export const recurrencePolicyDraftFactory = (m: CommercetoolsMock) =>
|
|
9
|
+
Factory.define<
|
|
10
|
+
RecurrencePolicyDraft,
|
|
11
|
+
RecurrencePolicyDraft,
|
|
12
|
+
RecurrencePolicy
|
|
13
|
+
>(({ sequence, onCreate }) => {
|
|
14
|
+
onCreate(async (draft) => {
|
|
15
|
+
const response = await m.app.inject({
|
|
16
|
+
method: "POST",
|
|
17
|
+
url: "/dummy/recurrence-policies",
|
|
18
|
+
payload: draft,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
return response.json();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
key: `recurrence-policy-${sequence}`,
|
|
26
|
+
name: { en: `Recurrence Policy ${sequence}` },
|
|
27
|
+
schedule: {
|
|
28
|
+
type: "standard",
|
|
29
|
+
value: 1,
|
|
30
|
+
intervalUnit: "Months",
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
RecurringOrder,
|
|
3
|
+
RecurringOrderDraft,
|
|
4
|
+
} from "@commercetools/platform-sdk";
|
|
5
|
+
import { Factory } from "fishery";
|
|
6
|
+
import type { CommercetoolsMock } from "#src/ctMock.ts";
|
|
7
|
+
|
|
8
|
+
export const recurringOrderDraftFactory = (m: CommercetoolsMock) =>
|
|
9
|
+
Factory.define<RecurringOrderDraft, RecurringOrderDraft, RecurringOrder>(
|
|
10
|
+
({ sequence, onCreate }) => {
|
|
11
|
+
onCreate(async (draft) => {
|
|
12
|
+
const response = await m.app.inject({
|
|
13
|
+
method: "POST",
|
|
14
|
+
url: "/dummy/recurring-orders",
|
|
15
|
+
payload: draft,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
return response.json();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
key: `recurring-order-${sequence}`,
|
|
23
|
+
cart: {
|
|
24
|
+
typeId: "cart" as const,
|
|
25
|
+
id: "placeholder-cart-id",
|
|
26
|
+
},
|
|
27
|
+
cartVersion: 1,
|
|
28
|
+
startsAt: "2025-01-01T10:00:00.000Z",
|
|
29
|
+
expiresAt: "2025-12-31T23:59:59.000Z",
|
|
30
|
+
};
|
|
31
|
+
},
|
|
32
|
+
);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Review, ReviewDraft } from "@commercetools/platform-sdk";
|
|
2
|
+
import { Factory } from "fishery";
|
|
3
|
+
import type { CommercetoolsMock } from "#src/ctMock.ts";
|
|
4
|
+
|
|
5
|
+
export const reviewDraftFactory = (m: CommercetoolsMock) =>
|
|
6
|
+
Factory.define<ReviewDraft, ReviewDraft, Review>(({ sequence, onCreate }) => {
|
|
7
|
+
onCreate(async (draft) => {
|
|
8
|
+
const response = await m.app.inject({
|
|
9
|
+
method: "POST",
|
|
10
|
+
url: "/dummy/reviews",
|
|
11
|
+
payload: draft,
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
return response.json();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
key: `review-${sequence}`,
|
|
19
|
+
authorName: `Author ${sequence}`,
|
|
20
|
+
title: `Review ${sequence}`,
|
|
21
|
+
text: `Review text ${sequence}`,
|
|
22
|
+
rating: 5,
|
|
23
|
+
};
|
|
24
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ShippingMethod,
|
|
3
|
+
ShippingMethodDraft,
|
|
4
|
+
} from "@commercetools/platform-sdk";
|
|
5
|
+
import { Factory } from "fishery";
|
|
6
|
+
import type { CommercetoolsMock } from "#src/ctMock.ts";
|
|
7
|
+
|
|
8
|
+
export const shippingMethodDraftFactory = (m: CommercetoolsMock) =>
|
|
9
|
+
Factory.define<ShippingMethodDraft, ShippingMethodDraft, ShippingMethod>(
|
|
10
|
+
({ sequence, onCreate }) => {
|
|
11
|
+
onCreate(async (draft) => {
|
|
12
|
+
const response = await m.app.inject({
|
|
13
|
+
method: "POST",
|
|
14
|
+
url: "/dummy/shipping-methods",
|
|
15
|
+
payload: draft,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
return response.json();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
name: `Shipping Method ${sequence}`,
|
|
23
|
+
taxCategory: {
|
|
24
|
+
typeId: "tax-category",
|
|
25
|
+
key: `tax-category-${sequence}`,
|
|
26
|
+
},
|
|
27
|
+
isDefault: true,
|
|
28
|
+
zoneRates: [],
|
|
29
|
+
};
|
|
30
|
+
},
|
|
31
|
+
);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ShoppingList,
|
|
3
|
+
ShoppingListDraft,
|
|
4
|
+
} from "@commercetools/platform-sdk";
|
|
5
|
+
import { Factory } from "fishery";
|
|
6
|
+
import type { CommercetoolsMock } from "#src/ctMock.ts";
|
|
7
|
+
|
|
8
|
+
export const shoppingListDraftFactory = (m: CommercetoolsMock) =>
|
|
9
|
+
Factory.define<ShoppingListDraft, ShoppingListDraft, ShoppingList>(
|
|
10
|
+
({ sequence, onCreate }) => {
|
|
11
|
+
onCreate(async (draft) => {
|
|
12
|
+
const response = await m.app.inject({
|
|
13
|
+
method: "POST",
|
|
14
|
+
url: "/dummy/shopping-lists",
|
|
15
|
+
payload: draft,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
return response.json();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
name: { en: `Shopping List ${sequence}` },
|
|
23
|
+
};
|
|
24
|
+
},
|
|
25
|
+
);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
StandalonePrice,
|
|
3
|
+
StandalonePriceDraft,
|
|
4
|
+
} from "@commercetools/platform-sdk";
|
|
5
|
+
import { Factory } from "fishery";
|
|
6
|
+
import type { CommercetoolsMock } from "#src/ctMock.ts";
|
|
7
|
+
|
|
8
|
+
export const standalonePriceDraftFactory = (m: CommercetoolsMock) =>
|
|
9
|
+
Factory.define<StandalonePriceDraft, StandalonePriceDraft, StandalonePrice>(
|
|
10
|
+
({ sequence, onCreate }) => {
|
|
11
|
+
onCreate(async (draft) => {
|
|
12
|
+
const response = await m.app.inject({
|
|
13
|
+
method: "POST",
|
|
14
|
+
url: "/dummy/standalone-prices",
|
|
15
|
+
payload: draft,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
return response.json();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
key: `standalone-price-${sequence}`,
|
|
23
|
+
sku: `sku-${sequence}`,
|
|
24
|
+
value: {
|
|
25
|
+
centAmount: 1000,
|
|
26
|
+
currencyCode: "EUR",
|
|
27
|
+
},
|
|
28
|
+
active: true,
|
|
29
|
+
};
|
|
30
|
+
},
|
|
31
|
+
);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { State, StateDraft } from "@commercetools/platform-sdk";
|
|
2
|
+
import { Factory } from "fishery";
|
|
3
|
+
import type { CommercetoolsMock } from "#src/ctMock.ts";
|
|
4
|
+
|
|
5
|
+
export const stateDraftFactory = (m: CommercetoolsMock) =>
|
|
6
|
+
Factory.define<StateDraft, StateDraft, State>(({ sequence, onCreate }) => {
|
|
7
|
+
onCreate(async (draft) => {
|
|
8
|
+
const response = await m.app.inject({
|
|
9
|
+
method: "POST",
|
|
10
|
+
url: "/dummy/states",
|
|
11
|
+
payload: draft,
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
return response.json();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
key: `state-${sequence}`,
|
|
19
|
+
type: "PaymentState",
|
|
20
|
+
};
|
|
21
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Store, StoreDraft } from "@commercetools/platform-sdk";
|
|
2
|
+
import { Factory } from "fishery";
|
|
3
|
+
import type { CommercetoolsMock } from "#src/ctMock.ts";
|
|
4
|
+
|
|
5
|
+
export const storeDraftFactory = (m: CommercetoolsMock) =>
|
|
6
|
+
Factory.define<StoreDraft, StoreDraft, Store>(({ sequence, onCreate }) => {
|
|
7
|
+
onCreate(async (draft) => {
|
|
8
|
+
const response = await m.app.inject({
|
|
9
|
+
method: "POST",
|
|
10
|
+
url: "/dummy/stores",
|
|
11
|
+
payload: draft,
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
return response.json();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
key: `store-${sequence}`,
|
|
19
|
+
name: { en: `Store ${sequence}` },
|
|
20
|
+
languages: [],
|
|
21
|
+
countries: [],
|
|
22
|
+
distributionChannels: [],
|
|
23
|
+
supplyChannels: [],
|
|
24
|
+
productSelections: [],
|
|
25
|
+
};
|
|
26
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Subscription,
|
|
3
|
+
SubscriptionDraft,
|
|
4
|
+
} from "@commercetools/platform-sdk";
|
|
5
|
+
import { Factory } from "fishery";
|
|
6
|
+
import type { CommercetoolsMock } from "#src/ctMock.ts";
|
|
7
|
+
|
|
8
|
+
export const subscriptionDraftFactory = (m: CommercetoolsMock) =>
|
|
9
|
+
Factory.define<SubscriptionDraft, SubscriptionDraft, Subscription>(
|
|
10
|
+
({ sequence, onCreate }) => {
|
|
11
|
+
onCreate(async (draft) => {
|
|
12
|
+
const response = await m.app.inject({
|
|
13
|
+
method: "POST",
|
|
14
|
+
url: "/dummy/subscriptions",
|
|
15
|
+
payload: draft,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
return response.json();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
key: `subscription-${sequence}`,
|
|
23
|
+
destination: {
|
|
24
|
+
type: "SQS",
|
|
25
|
+
queueUrl: `https://sqs.us-east-1.amazonaws.com/123456789/queue-${sequence}`,
|
|
26
|
+
accessKey: "AKIAIOSFODNN7EXAMPLE",
|
|
27
|
+
accessSecret: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
|
|
28
|
+
region: "us-east-1",
|
|
29
|
+
},
|
|
30
|
+
messages: [
|
|
31
|
+
{
|
|
32
|
+
resourceTypeId: "order",
|
|
33
|
+
types: ["OrderCreated"],
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
};
|
|
37
|
+
},
|
|
38
|
+
);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
TaxCategory,
|
|
3
|
+
TaxCategoryDraft,
|
|
4
|
+
} from "@commercetools/platform-sdk";
|
|
5
|
+
import { Factory } from "fishery";
|
|
6
|
+
import type { CommercetoolsMock } from "#src/ctMock.ts";
|
|
7
|
+
|
|
8
|
+
export const taxCategoryDraftFactory = (m: CommercetoolsMock) =>
|
|
9
|
+
Factory.define<TaxCategoryDraft, TaxCategoryDraft, TaxCategory>(
|
|
10
|
+
({ sequence, onCreate }) => {
|
|
11
|
+
onCreate(async (draft) => {
|
|
12
|
+
const response = await m.app.inject({
|
|
13
|
+
method: "POST",
|
|
14
|
+
url: "/dummy/tax-categories",
|
|
15
|
+
payload: draft,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
return response.json();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
key: `tax-category-${sequence}`,
|
|
23
|
+
name: `Tax Category ${sequence}`,
|
|
24
|
+
rates: [],
|
|
25
|
+
};
|
|
26
|
+
},
|
|
27
|
+
);
|
package/src/testing/type.ts
CHANGED
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
import type { Type, TypeDraft } from "@commercetools/platform-sdk";
|
|
2
2
|
import { Factory } from "fishery";
|
|
3
|
-
import supertest from "supertest";
|
|
4
3
|
import type { CommercetoolsMock } from "#src/ctMock.ts";
|
|
5
4
|
|
|
6
5
|
export const typeDraftFactory = (m: CommercetoolsMock) =>
|
|
7
|
-
Factory.define<TypeDraft, TypeDraft, Type>(({ onCreate }) => {
|
|
6
|
+
Factory.define<TypeDraft, TypeDraft, Type>(({ sequence, onCreate }) => {
|
|
8
7
|
onCreate(async (draft) => {
|
|
9
|
-
const response = await
|
|
8
|
+
const response = await m.app.inject({
|
|
9
|
+
method: "POST",
|
|
10
|
+
url: "/dummy/types",
|
|
11
|
+
payload: draft,
|
|
12
|
+
});
|
|
10
13
|
|
|
11
|
-
return response.
|
|
14
|
+
return response.json();
|
|
12
15
|
});
|
|
13
16
|
|
|
14
17
|
return {
|
|
15
|
-
key:
|
|
16
|
-
name: { en:
|
|
18
|
+
key: `type-${sequence}`,
|
|
19
|
+
name: { en: `Type Name ${sequence}` },
|
|
17
20
|
resourceTypeIds: ["product"],
|
|
18
21
|
description: { en: "Type description" },
|
|
19
22
|
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Zone, ZoneDraft } from "@commercetools/platform-sdk";
|
|
2
|
+
import { Factory } from "fishery";
|
|
3
|
+
import type { CommercetoolsMock } from "#src/ctMock.ts";
|
|
4
|
+
|
|
5
|
+
export const zoneDraftFactory = (m: CommercetoolsMock) =>
|
|
6
|
+
Factory.define<ZoneDraft, ZoneDraft, Zone>(({ sequence, onCreate }) => {
|
|
7
|
+
onCreate(async (draft) => {
|
|
8
|
+
const response = await m.app.inject({
|
|
9
|
+
method: "POST",
|
|
10
|
+
url: "/dummy/zones",
|
|
11
|
+
payload: draft,
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
return response.json();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
key: `zone-${sequence}`,
|
|
19
|
+
name: `Zone ${sequence}`,
|
|
20
|
+
locations: [{ country: "NL" }],
|
|
21
|
+
};
|
|
22
|
+
});
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { formatDetailedErrorMessage } from "./validate.ts";
|
|
4
|
+
|
|
5
|
+
describe("formatDetailedErrorMessage", () => {
|
|
6
|
+
it("formats missing required field", () => {
|
|
7
|
+
const schema = z.object({ name: z.string() });
|
|
8
|
+
const result = schema.safeParse({});
|
|
9
|
+
expect(result.success).toBe(false);
|
|
10
|
+
if (!result.success) {
|
|
11
|
+
expect(formatDetailedErrorMessage(result.error)).toBe(
|
|
12
|
+
"name: Missing required value",
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it("formats wrong type (string expected, got number)", () => {
|
|
18
|
+
const schema = z.object({ name: z.string() });
|
|
19
|
+
const result = schema.safeParse({ name: 123 });
|
|
20
|
+
expect(result.success).toBe(false);
|
|
21
|
+
if (!result.success) {
|
|
22
|
+
expect(formatDetailedErrorMessage(result.error)).toBe(
|
|
23
|
+
"name: JSON String expected.",
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("formats wrong type (number expected, got string)", () => {
|
|
29
|
+
const schema = z.object({ count: z.number() });
|
|
30
|
+
const result = schema.safeParse({ count: "abc" });
|
|
31
|
+
expect(result.success).toBe(false);
|
|
32
|
+
if (!result.success) {
|
|
33
|
+
expect(formatDetailedErrorMessage(result.error)).toBe(
|
|
34
|
+
"count: JSON Number expected.",
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("formats wrong type (boolean expected)", () => {
|
|
40
|
+
const schema = z.object({ active: z.boolean() });
|
|
41
|
+
const result = schema.safeParse({ active: "yes" });
|
|
42
|
+
expect(result.success).toBe(false);
|
|
43
|
+
if (!result.success) {
|
|
44
|
+
expect(formatDetailedErrorMessage(result.error)).toBe(
|
|
45
|
+
"active: JSON Boolean expected.",
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("formats wrong type (object expected)", () => {
|
|
51
|
+
const schema = z.object({ data: z.object({ id: z.string() }) });
|
|
52
|
+
const result = schema.safeParse({ data: "not-an-object" });
|
|
53
|
+
expect(result.success).toBe(false);
|
|
54
|
+
if (!result.success) {
|
|
55
|
+
expect(formatDetailedErrorMessage(result.error)).toBe(
|
|
56
|
+
"data: JSON object expected.",
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it("formats wrong type (array expected)", () => {
|
|
62
|
+
const schema = z.object({ items: z.array(z.string()) });
|
|
63
|
+
const result = schema.safeParse({ items: "not-an-array" });
|
|
64
|
+
expect(result.success).toBe(false);
|
|
65
|
+
if (!result.success) {
|
|
66
|
+
expect(formatDetailedErrorMessage(result.error)).toBe(
|
|
67
|
+
"items: JSON Array expected.",
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it("formats invalid enum value", () => {
|
|
73
|
+
const schema = z.object({ role: z.enum(["Admin", "User"]) });
|
|
74
|
+
const result = schema.safeParse({ role: "SuperAdmin" });
|
|
75
|
+
expect(result.success).toBe(false);
|
|
76
|
+
if (!result.success) {
|
|
77
|
+
expect(formatDetailedErrorMessage(result.error)).toBe(
|
|
78
|
+
"role: Invalid enum value. Expected one of: 'Admin', 'User'",
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it("formats nested field errors with dot path", () => {
|
|
84
|
+
const schema = z.object({
|
|
85
|
+
address: z.object({ country: z.string() }),
|
|
86
|
+
});
|
|
87
|
+
const result = schema.safeParse({ address: { country: 123 } });
|
|
88
|
+
expect(result.success).toBe(false);
|
|
89
|
+
if (!result.success) {
|
|
90
|
+
expect(formatDetailedErrorMessage(result.error)).toBe(
|
|
91
|
+
"address.country: JSON String expected.",
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it("formats refine errors (custom code)", () => {
|
|
97
|
+
const schema = z
|
|
98
|
+
.object({ id: z.string().optional(), key: z.string().optional() })
|
|
99
|
+
.refine((data) => data.id !== undefined || data.key !== undefined, {
|
|
100
|
+
message: "Either 'id' or 'key' must be provided",
|
|
101
|
+
});
|
|
102
|
+
const result = schema.safeParse({});
|
|
103
|
+
expect(result.success).toBe(false);
|
|
104
|
+
if (!result.success) {
|
|
105
|
+
expect(formatDetailedErrorMessage(result.error)).toBe(
|
|
106
|
+
"Either 'id' or 'key' must be provided",
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it("uses first issue only when multiple errors exist", () => {
|
|
112
|
+
const schema = z.object({ a: z.string(), b: z.number() });
|
|
113
|
+
const result = schema.safeParse({});
|
|
114
|
+
expect(result.success).toBe(false);
|
|
115
|
+
if (!result.success) {
|
|
116
|
+
// Should report the first missing field only
|
|
117
|
+
expect(formatDetailedErrorMessage(result.error)).toBe(
|
|
118
|
+
"a: Missing required value",
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
});
|
package/src/validate.ts
CHANGED
|
@@ -1,18 +1,89 @@
|
|
|
1
1
|
import type { InvalidJsonInputError } from "@commercetools/platform-sdk";
|
|
2
2
|
import type { z } from "zod";
|
|
3
|
-
import { fromZodError } from "zod-validation-error";
|
|
4
3
|
import { CommercetoolsError } from "./exceptions.ts";
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Format a Zod error into a commercetools-style detailedErrorMessage.
|
|
7
|
+
*
|
|
8
|
+
* The real API uses messages like:
|
|
9
|
+
* "quantityOnStock: Missing required value"
|
|
10
|
+
* "name: JSON object expected."
|
|
11
|
+
* "roles: Invalid enum value. Expected one of: 'InventorySupply', ..."
|
|
12
|
+
*
|
|
13
|
+
* We use the first issue only, matching the real API behaviour of reporting
|
|
14
|
+
* a single detailed message.
|
|
15
|
+
*/
|
|
16
|
+
export function formatDetailedErrorMessage(error: z.ZodError): string {
|
|
17
|
+
const issue = error.issues[0];
|
|
18
|
+
if (!issue) return "Unknown error";
|
|
19
|
+
|
|
20
|
+
const path = issue.path.join(".");
|
|
21
|
+
|
|
22
|
+
// Missing required field: Zod reports invalid_type with "received undefined"
|
|
23
|
+
if (
|
|
24
|
+
issue.code === "invalid_type" &&
|
|
25
|
+
issue.message.includes("received undefined")
|
|
26
|
+
) {
|
|
27
|
+
return `${path}: Missing required value`;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Wrong type (e.g. string received instead of number)
|
|
31
|
+
if (issue.code === "invalid_type") {
|
|
32
|
+
const expected = (issue as any).expected;
|
|
33
|
+
switch (expected) {
|
|
34
|
+
case "string":
|
|
35
|
+
return `${path}: JSON String expected.`;
|
|
36
|
+
case "number":
|
|
37
|
+
case "integer":
|
|
38
|
+
return `${path}: JSON Number expected.`;
|
|
39
|
+
case "boolean":
|
|
40
|
+
return `${path}: JSON Boolean expected.`;
|
|
41
|
+
case "object":
|
|
42
|
+
return `${path}: JSON object expected.`;
|
|
43
|
+
case "array":
|
|
44
|
+
return `${path}: JSON Array expected.`;
|
|
45
|
+
default:
|
|
46
|
+
return `${path}: Invalid type: expected ${expected}`;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Invalid enum value
|
|
51
|
+
if (issue.code === "invalid_value") {
|
|
52
|
+
const values = (issue as any).values;
|
|
53
|
+
if (Array.isArray(values)) {
|
|
54
|
+
const formatted = values.map((v: string) => `'${v}'`).join(", ");
|
|
55
|
+
return `${path}: Invalid enum value. Expected one of: ${formatted}`;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Refine errors (e.g. ResourceIdentifier id-or-key check)
|
|
60
|
+
if (issue.code === "custom") {
|
|
61
|
+
return issue.message;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Fallback: use Zod's message with path prefix
|
|
65
|
+
return path ? `${path}: ${issue.message}` : issue.message;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export const validateData = <T>(data: any, schema: z.ZodType) => {
|
|
69
|
+
const result = schema.safeParse(data);
|
|
70
|
+
if (result.success) {
|
|
9
71
|
return data as T;
|
|
10
|
-
}
|
|
11
|
-
|
|
72
|
+
}
|
|
73
|
+
throw new CommercetoolsError<InvalidJsonInputError>({
|
|
74
|
+
code: "InvalidJsonInput",
|
|
75
|
+
message: "Request body does not contain valid JSON.",
|
|
76
|
+
detailedErrorMessage: formatDetailedErrorMessage(result.error),
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export const validateDraft = (data: unknown, schema: z.ZodType): void => {
|
|
81
|
+
const result = schema.safeParse(data);
|
|
82
|
+
if (!result.success) {
|
|
12
83
|
throw new CommercetoolsError<InvalidJsonInputError>({
|
|
13
84
|
code: "InvalidJsonInput",
|
|
14
85
|
message: "Request body does not contain valid JSON.",
|
|
15
|
-
detailedErrorMessage:
|
|
86
|
+
detailedErrorMessage: formatDetailedErrorMessage(result.error),
|
|
16
87
|
});
|
|
17
88
|
}
|
|
18
89
|
};
|
package/src/.env
DELETED
|
File without changes
|